/*************************************************************************** * Copyright (c) 2014 Luke Parry * * * * 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 #endif //#ifndef _PreComp_ # include # include # include # include # include # include # include # include # include # include # include # include # include # include # include # include # include # include # include "MDIViewPage.h" # include "ViewProviderPage.h" using namespace TechDrawGui; using namespace std; //internal functions bool _checkSelection(Gui::Command* cmd); int _isValidSingleEdge(Gui::Command* cmd, bool trueDim=true); bool _isValidVertexes(Gui::Command* cmd); int _isValidEdgeToEdge(Gui::Command* cmd, bool trueDim=true); bool _isTrueAllowed(TechDraw::DrawViewPart* objFeat, const std::vector &SubNames); enum EdgeType{ isInvalid, isHorizontal, isVertical, isDiagonal, isCircle, isCurve, isAngle }; //=========================================================================== // TechDraw_NewDimension //=========================================================================== DEF_STD_CMD(CmdTechDrawNewDimension); CmdTechDrawNewDimension::CmdTechDrawNewDimension() : Command("TechDraw_NewDimension") { sAppModule = "Drawing"; sGroup = QT_TR_NOOP("Drawing"); sMenuText = QT_TR_NOOP("Insert a dimension into the drawing"); sToolTipText = QT_TR_NOOP("Insert a new dimension"); sWhatsThis = "TechDraw_NewDimension"; sStatusTip = sToolTipText; sPixmap = "Dimension"; } void CmdTechDrawNewDimension::activated(int iMsg) { bool result = _checkSelection(this); if (!result) return; std::vector selection = getSelection().getSelectionEx(); TechDraw::DrawViewPart * objFeat = dynamic_cast(selection[0].getObject()); const std::vector &SubNames = selection[0].getSubNames(); TechDraw::DrawViewDimension *dim = 0; std::string FeatName = getUniqueObjectName("Dimension"); std::string dimType; bool centerLine = false; std::vector objs; std::vector subs; //selected edge(s) must have valid reference to Source edge for True Dimension //otherwise Dimension must be Projected bool trueDimAllowed = _isTrueAllowed(objFeat,SubNames); int edgeType = _isValidSingleEdge(this,trueDimAllowed); if (edgeType) { if (edgeType < isCircle) { dimType = "Distance"; objs.push_back(objFeat); subs.push_back(SubNames[0]); } else if (edgeType == isCircle) { dimType = "Radius"; centerLine = true; } else { dimType = "Radius"; } } else if (_isValidVertexes(this)) { dimType = "Distance"; objs.push_back(objFeat); objs.push_back(objFeat); subs.push_back(SubNames[0]); subs.push_back(SubNames[1]); } else if (_isValidEdgeToEdge(this)) { int edgeCase = _isValidEdgeToEdge(this); objs.push_back(objFeat); objs.push_back(objFeat); subs.push_back(SubNames[0]); subs.push_back(SubNames[1]); switch (edgeCase) { //TODO: This didn't have the breaks in it before 17 May, but didn't // seem to crash either, so should check whether execution can even // get here -Ian- case isHorizontal: dimType = "DistanceX"; break; case isVertical: dimType = "DistanceY"; break; case isDiagonal: dimType = "Distance"; break; case isAngle: dimType = "Angle"; default: break; } } else { QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Incorrect Selection"), QObject::tr("Can't make a Dimension from this selection")); return; } openCommand("Create Dimension"); doCommand(Doc,"App.activeDocument().addObject('TechDraw::DrawViewDimension','%s')",FeatName.c_str()); doCommand(Doc,"App.activeDocument().%s.Type = '%s'",FeatName.c_str() ,dimType.c_str()); if (centerLine) { doCommand(Doc,"App.activeDocument().%s.CentreLines = True", FeatName.c_str()); } else { doCommand(Doc,"App.activeDocument().%s.CentreLines = False", FeatName.c_str()); } std::string contentStr; if (dimType == "Angle") { contentStr = "%value%\x00b0"; } else if (dimType == "Radius") { contentStr = "r%value%"; } doCommand(Doc,"App.activeDocument().%s.FormatSpec = '%s'",FeatName.c_str() ,contentStr.c_str()); dim = dynamic_cast(getDocument()->getObject(FeatName.c_str())); dim->References.setValues(objs, subs); // make a True dimension if you can, Projected otherwise if (trueDimAllowed) { doCommand(Doc,"App.activeDocument().%s.ProjectionType = 'True'",FeatName.c_str()); } else { doCommand(Doc,"App.activeDocument().%s.ProjectionType = 'Projected'",FeatName.c_str()); } dim->execute(); std::vector pages = getDocument()->getObjectsOfType(TechDraw::DrawPage::getClassTypeId()); TechDraw::DrawPage *page = dynamic_cast(pages.front()); page->addView(page->getDocument()->getObject(FeatName.c_str())); commitCommand(); //Horrible hack to force Tree update double x = objFeat->X.getValue(); objFeat->X.setValue(x); } //=========================================================================== // TechDraw_NewRadiusDimension //=========================================================================== DEF_STD_CMD(CmdTechDrawNewRadiusDimension); CmdTechDrawNewRadiusDimension::CmdTechDrawNewRadiusDimension() : Command("TechDraw_NewRadiusDimension") { sAppModule = "Drawing"; sGroup = QT_TR_NOOP("Drawing"); sMenuText = QT_TR_NOOP("Insert a new radius dimension into the drawing"); sToolTipText = QT_TR_NOOP("Insert a new radius dimension feature for the selected view"); sWhatsThis = "TechDraw_NewRadiusDimension"; sStatusTip = sToolTipText; sPixmap = "Dimension_Radius"; } void CmdTechDrawNewRadiusDimension::activated(int iMsg) { bool result = _checkSelection(this); if (!result) return; std::vector selection = getSelection().getSelectionEx(); TechDraw::DrawViewPart * objFeat = dynamic_cast(selection[0].getObject()); const std::vector &SubNames = selection[0].getSubNames(); TechDraw::DrawViewDimension *dim = 0; std::string FeatName = getUniqueObjectName("Dimension"); bool centerLine = false; std::vector objs; std::vector subs; //selected edge(s) must have valid reference to Source edge for True Dimension //otherwise Dimension must be Projected bool trueDimAllowed = _isTrueAllowed(objFeat,SubNames); int edgeType = _isValidSingleEdge(this,trueDimAllowed); if (edgeType == isCircle) { centerLine = true; objs.push_back(objFeat); subs.push_back(SubNames[0]); } else { std::stringstream edgeMsg; edgeMsg << "Can't make a radius Dimension from this selection (edge type: " << edgeType << ")"; QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Incorrect Selection"), QObject::tr(edgeMsg.str().c_str())); return; } openCommand("Create Dimension"); doCommand(Doc,"App.activeDocument().addObject('TechDraw::DrawViewDimension','%s')",FeatName.c_str()); doCommand(Doc,"App.activeDocument().%s.Type = '%s'",FeatName.c_str() ,"Radius"); if (centerLine) { doCommand(Doc,"App.activeDocument().%s.CentreLines = True", FeatName.c_str()); } else { doCommand(Doc,"App.activeDocument().%s.CentreLines = False", FeatName.c_str()); } doCommand(Doc, "App.activeDocument().%s.FormatSpec = 'r%%value%%'", FeatName.c_str()); dim = dynamic_cast(getDocument()->getObject(FeatName.c_str())); dim->References.setValues(objs, subs); if (trueDimAllowed) { doCommand(Doc,"App.activeDocument().%s.ProjectionType = 'True'",FeatName.c_str()); } else { doCommand(Doc,"App.activeDocument().%s.ProjectionType = 'Projected'",FeatName.c_str()); } dim->execute(); std::vector pages = getDocument()->getObjectsOfType(TechDraw::DrawPage::getClassTypeId()); TechDraw::DrawPage *page = dynamic_cast(pages.front()); page->addView(page->getDocument()->getObject(FeatName.c_str())); commitCommand(); //Horrible hack to force Tree update double x = objFeat->X.getValue(); objFeat->X.setValue(x); } //=========================================================================== // TechDraw_NewDiameterDimension //=========================================================================== DEF_STD_CMD(CmdTechDrawNewDiameterDimension); CmdTechDrawNewDiameterDimension::CmdTechDrawNewDiameterDimension() : Command("TechDraw_NewDiameterDimension") { sAppModule = "Drawing"; sGroup = QT_TR_NOOP("Drawing"); sMenuText = QT_TR_NOOP("Insert a new diameter dimension into the drawing"); sToolTipText = QT_TR_NOOP("Insert a new diameter dimension feature for the selected view"); sWhatsThis = "TechDraw_NewDiameterDimension"; sStatusTip = sToolTipText; sPixmap = "Dimension_Diameter"; } void CmdTechDrawNewDiameterDimension::activated(int iMsg) { bool result = _checkSelection(this); if (!result) return; std::vector selection = getSelection().getSelectionEx(); TechDraw::DrawViewPart * objFeat = dynamic_cast(selection[0].getObject()); const std::vector &SubNames = selection[0].getSubNames(); TechDraw::DrawViewDimension *dim = 0; std::string FeatName = getUniqueObjectName("Dimension"); bool centerLine = false; std::vector objs; std::vector subs; //selected edge(s) must have valid reference to Source edge for True Dimension //otherwise Dimension must be Projected bool trueDimAllowed = _isTrueAllowed(objFeat,SubNames); int edgeType = _isValidSingleEdge(this,trueDimAllowed); if (edgeType == isCircle) { centerLine = true; objs.push_back(objFeat); subs.push_back(SubNames[0]); } else { std::stringstream edgeMsg; edgeMsg << "Can't make a diameter Dimension from this selection (edge type: " << edgeType << ")"; QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Incorrect Selection"), QObject::tr(edgeMsg.str().c_str())); return; } openCommand("Create Dimension"); doCommand(Doc,"App.activeDocument().addObject('TechDraw::DrawViewDimension','%s')",FeatName.c_str()); doCommand(Doc,"App.activeDocument().%s.Type = '%s'",FeatName.c_str() ,"Diameter"); if (centerLine) { doCommand(Doc,"App.activeDocument().%s.CentreLines = True", FeatName.c_str()); } else { doCommand(Doc,"App.activeDocument().%s.CentreLines = False", FeatName.c_str()); } doCommand(Doc, "App.activeDocument().%s.FormatSpec = '\u00d8%%value%%'", FeatName.c_str()); // \u00d8 is Capital O with stroke dim = dynamic_cast(getDocument()->getObject(FeatName.c_str())); dim->References.setValues(objs, subs); // make a True dimension if you can, Projected otherwise if (trueDimAllowed) { doCommand(Doc,"App.activeDocument().%s.ProjectionType = 'True'",FeatName.c_str()); } else { doCommand(Doc,"App.activeDocument().%s.ProjectionType = 'Projected'",FeatName.c_str()); } dim->execute(); std::vector pages = getDocument()->getObjectsOfType(TechDraw::DrawPage::getClassTypeId()); TechDraw::DrawPage *page = dynamic_cast(pages.front()); page->addView(page->getDocument()->getObject(FeatName.c_str())); commitCommand(); //Horrible hack to force Tree update double x = objFeat->X.getValue(); objFeat->X.setValue(x); } //=========================================================================== // TechDraw_NewLengthDimension //=========================================================================== DEF_STD_CMD(CmdTechDrawNewLengthDimension); CmdTechDrawNewLengthDimension::CmdTechDrawNewLengthDimension() : Command("TechDraw_NewLengthDimension") { sAppModule = "Drawing"; sGroup = QT_TR_NOOP("Drawing"); sMenuText = QT_TR_NOOP("Insert a new length dimension into the drawing"); sToolTipText = QT_TR_NOOP("Insert a new length dimension"); sWhatsThis = "TechDraw_NewLengthDimension"; sStatusTip = sToolTipText; sPixmap = "Dimension_Length"; } void CmdTechDrawNewLengthDimension::activated(int iMsg) { bool result = _checkSelection(this); if (!result) return; std::vector selection = getSelection().getSelectionEx(); TechDraw::DrawViewPart * objFeat = dynamic_cast(selection[0].getObject()); const std::vector &SubNames = selection[0].getSubNames(); TechDraw::DrawViewDimension *dim = 0; std::string FeatName = getUniqueObjectName("Dimension"); std::string dimType; std::vector objs; std::vector subs; //selected edge(s) must have valid reference to Source edge for True Dimension //otherwise Dimension must be Projected bool trueDimAllowed = _isTrueAllowed(objFeat,SubNames); int edgeType = _isValidSingleEdge(this,trueDimAllowed); if ((edgeType == isHorizontal) || (edgeType == isVertical) || (edgeType == isDiagonal)) { objs.push_back(objFeat); subs.push_back(SubNames[0]); } else if (_isValidVertexes(this)) { objs.push_back(objFeat); objs.push_back(objFeat); subs.push_back(SubNames[0]); subs.push_back(SubNames[1]); } else if ((_isValidEdgeToEdge(this) == isHorizontal) || (_isValidEdgeToEdge(this) == isVertical) || (_isValidEdgeToEdge(this) == isVertical)) { objs.push_back(objFeat); objs.push_back(objFeat); subs.push_back(SubNames[0]); subs.push_back(SubNames[1]); } else { std::stringstream edgeMsg; edgeMsg << "Can't make a length Dimension from this selection (edge type: " << edgeType << ")"; QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Incorrect Selection"), QObject::tr(edgeMsg.str().c_str())); return; } openCommand("Create Dimension"); doCommand(Doc,"App.activeDocument().addObject('TechDraw::DrawViewDimension','%s')", FeatName.c_str()); doCommand(Doc,"App.activeDocument().%s.Type = '%s'", FeatName.c_str() , "Distance"); dim = dynamic_cast(getDocument()->getObject(FeatName.c_str())); dim->References.setValues(objs, subs); doCommand(Doc, "App.activeDocument().%s.FormatSpec = '%%value%%'", FeatName.c_str()); // make a True dimension if you can, Projected otherwise if (trueDimAllowed) { doCommand(Doc,"App.activeDocument().%s.ProjectionType = 'True'",FeatName.c_str()); } else { doCommand(Doc,"App.activeDocument().%s.ProjectionType = 'Projected'",FeatName.c_str()); } dim->execute(); std::vector pages = getDocument()->getObjectsOfType(TechDraw::DrawPage::getClassTypeId()); TechDraw::DrawPage *page = dynamic_cast(pages.front()); page->addView(page->getDocument()->getObject(FeatName.c_str())); commitCommand(); //Horrible hack to force Tree update double x = objFeat->X.getValue(); objFeat->X.setValue(x); } //=========================================================================== // TechDraw_NewDistanceXDimension //=========================================================================== DEF_STD_CMD(CmdTechDrawNewDistanceXDimension); CmdTechDrawNewDistanceXDimension::CmdTechDrawNewDistanceXDimension() : Command("TechDraw_NewDistanceXDimension") { sAppModule = "Drawing"; sGroup = QT_TR_NOOP("Drawing"); sMenuText = QT_TR_NOOP("Insert a new horizontal dimension into the drawing"); sToolTipText = QT_TR_NOOP("Insert a new horizontal-distance dimension"); sWhatsThis = "TechDraw_NewDistanceXDimension"; sStatusTip = sToolTipText; sPixmap = "Dimension_Horizontal"; } void CmdTechDrawNewDistanceXDimension::activated(int iMsg) { bool result = _checkSelection(this); if (!result) return; std::vector selection = getSelection().getSelectionEx(); TechDraw::DrawViewPart * objFeat = dynamic_cast(selection[0].getObject()); const std::vector &SubNames = selection[0].getSubNames(); TechDraw::DrawViewDimension *dim = 0; std::string FeatName = getUniqueObjectName("Dimension"); std::string dimType; std::vector objs; std::vector subs; //selected edge(s) must have valid reference to Source edge for True Dimension //otherwise Dimension must be Projected bool trueDimAllowed = _isTrueAllowed(objFeat,SubNames); int edgeType = _isValidSingleEdge(this,trueDimAllowed); if ((edgeType == isHorizontal) || (edgeType == isDiagonal)) { objs.push_back(objFeat); subs.push_back(SubNames[0]); } else if (_isValidVertexes(this)) { objs.push_back(objFeat); objs.push_back(objFeat); subs.push_back(SubNames[0]); subs.push_back(SubNames[1]); } else if (_isValidEdgeToEdge(this) == isHorizontal) { objs.push_back(objFeat); objs.push_back(objFeat); subs.push_back(SubNames[0]); subs.push_back(SubNames[1]); } else { std::stringstream edgeMsg; edgeMsg << "Can't make a horizontal Dimension from this selection (edge type: " << edgeType << ")"; QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Incorrect Selection"), QObject::tr(edgeMsg.str().c_str())); return; } openCommand("Create Dimension"); doCommand(Doc,"App.activeDocument().addObject('TechDraw::DrawViewDimension','%s')",FeatName.c_str()); doCommand(Doc,"App.activeDocument().%s.Type = '%s'",FeatName.c_str() ,"DistanceX"); dim = dynamic_cast(getDocument()->getObject(FeatName.c_str())); dim->References.setValues(objs, subs); doCommand(Doc, "App.activeDocument().%s.FormatSpec = '%%value%%'", FeatName.c_str()); // make a True dimension if you can, Projected otherwise if (trueDimAllowed) { doCommand(Doc,"App.activeDocument().%s.ProjectionType = 'True'",FeatName.c_str()); } else { doCommand(Doc,"App.activeDocument().%s.ProjectionType = 'Projected'",FeatName.c_str()); } dim->execute(); std::vector pages = getDocument()->getObjectsOfType(TechDraw::DrawPage::getClassTypeId()); TechDraw::DrawPage *page = dynamic_cast(pages.front()); page->addView(page->getDocument()->getObject(FeatName.c_str())); commitCommand(); //Horrible hack to force Tree update double x = objFeat->X.getValue(); objFeat->X.setValue(x); } //=========================================================================== // TechDraw_NewDistanceYDimension //=========================================================================== DEF_STD_CMD(CmdTechDrawNewDistanceYDimension); CmdTechDrawNewDistanceYDimension::CmdTechDrawNewDistanceYDimension() : Command("TechDraw_NewDistanceYDimension") { sAppModule = "Drawing"; sGroup = QT_TR_NOOP("Drawing"); sMenuText = QT_TR_NOOP("Insert a new vertical dimension into the drawing"); sToolTipText = QT_TR_NOOP("Insert a new vertical distance dimension"); sWhatsThis = "TechDraw_NewDistanceYDimension"; sStatusTip = sToolTipText; sPixmap = "Dimension_Vertical"; } void CmdTechDrawNewDistanceYDimension::activated(int iMsg) { bool result = _checkSelection(this); if (!result) return; std::vector selection = getSelection().getSelectionEx(); TechDraw::DrawViewPart * objFeat = dynamic_cast(selection[0].getObject()); const std::vector &SubNames = selection[0].getSubNames(); TechDraw::DrawViewDimension *dim = 0; std::string FeatName = getUniqueObjectName("Dimension"); std::string dimType; std::vector objs; std::vector subs; //selected edge(s) must have valid reference to Source edge for True Dimension //otherwise Dimension must be Projected bool trueDimAllowed = _isTrueAllowed(objFeat,SubNames); int edgeType = _isValidSingleEdge(this,trueDimAllowed); if ((edgeType == isVertical) || (edgeType == isDiagonal)) { objs.push_back(objFeat); subs.push_back(SubNames[0]); } else if (_isValidVertexes(this)) { objs.push_back(objFeat); objs.push_back(objFeat); subs.push_back(SubNames[0]); subs.push_back(SubNames[1]); } else if (_isValidEdgeToEdge(this) == isVertical) { objs.push_back(objFeat); objs.push_back(objFeat); subs.push_back(SubNames[0]); subs.push_back(SubNames[1]); } else { std::stringstream edgeMsg; edgeMsg << "Can't make a vertical Dimension from this selection (edge type: " << edgeType << ")"; QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Incorrect Selection"), QObject::tr(edgeMsg.str().c_str())); return; } openCommand("Create Dimension"); doCommand(Doc,"App.activeDocument().addObject('TechDraw::DrawViewDimension','%s')",FeatName.c_str()); doCommand(Doc,"App.activeDocument().%s.Type = '%s'",FeatName.c_str() ,"DistanceY"); dim = dynamic_cast(getDocument()->getObject(FeatName.c_str())); dim->References.setValues(objs, subs); doCommand(Doc, "App.activeDocument().%s.FormatSpec = '%%value%%'", FeatName.c_str()); // make a True dimension if you can, Projected otherwise if (trueDimAllowed) { doCommand(Doc,"App.activeDocument().%s.ProjectionType = 'True'",FeatName.c_str()); } else { doCommand(Doc,"App.activeDocument().%s.ProjectionType = 'Projected'",FeatName.c_str()); } dim->execute(); std::vector pages = getDocument()->getObjectsOfType(TechDraw::DrawPage::getClassTypeId()); TechDraw::DrawPage *page = dynamic_cast(pages.front()); page->addView(page->getDocument()->getObject(FeatName.c_str())); commitCommand(); //Horrible hack to force Tree update double x = objFeat->X.getValue(); objFeat->X.setValue(x); } //=========================================================================== // TechDraw_NewAngleDimension //=========================================================================== DEF_STD_CMD(CmdTechDrawNewAngleDimension); CmdTechDrawNewAngleDimension::CmdTechDrawNewAngleDimension() : Command("TechDraw_NewAngleDimension") { sAppModule = "Drawing"; sGroup = QT_TR_NOOP("Drawing"); sMenuText = QT_TR_NOOP("Insert a new angle dimension into the drawing"); sToolTipText = QT_TR_NOOP("Insert a new angle dimension"); sWhatsThis = "TechDraw_NewAngleDimension"; sStatusTip = sToolTipText; sPixmap = "Dimension_Angle"; } void CmdTechDrawNewAngleDimension::activated(int iMsg) { bool result = _checkSelection(this); if (!result) return; std::vector selection = getSelection().getSelectionEx(); TechDraw::DrawViewPart * objFeat = dynamic_cast(selection[0].getObject()); const std::vector &SubNames = selection[0].getSubNames(); TechDraw::DrawViewDimension *dim = 0; std::string FeatName = getUniqueObjectName("Dimension"); std::vector objs; std::vector subs; //selected edge(s) must have valid reference to Source edge for True Dimension //otherwise Dimension must be Projected bool trueDimAllowed = _isTrueAllowed(objFeat,SubNames); int edgeType = _isValidEdgeToEdge(this,trueDimAllowed); if (edgeType == isAngle) { objs.push_back(objFeat); objs.push_back(objFeat); subs.push_back(SubNames[0]); subs.push_back(SubNames[1]); } else { QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Incorrect Selection"), QObject::tr("Can't make an angle Dimension from this selection")); return; } openCommand("Create Dimension"); doCommand(Doc,"App.activeDocument().addObject('TechDraw::DrawViewDimension','%s')",FeatName.c_str()); doCommand(Doc,"App.activeDocument().%s.Type = '%s'",FeatName.c_str() ,"Angle"); doCommand(Doc,"App.activeDocument().%s.FormatSpec = '%s'",FeatName.c_str() ,"%value%\u00b0"); // \u00b0 is degree sign dim = dynamic_cast(getDocument()->getObject(FeatName.c_str())); dim->References.setValues(objs, subs); // make a True dimension if you can, Projected otherwise if (trueDimAllowed) { doCommand(Doc,"App.activeDocument().%s.ProjectionType = 'True'",FeatName.c_str()); } else { doCommand(Doc,"App.activeDocument().%s.ProjectionType = 'Projected'",FeatName.c_str()); } dim->execute(); std::vector pages = getDocument()->getObjectsOfType(TechDraw::DrawPage::getClassTypeId()); TechDraw::DrawPage *page = dynamic_cast(pages.front()); page->addView(page->getDocument()->getObject(FeatName.c_str())); commitCommand(); //Horrible hack to force Tree update double x = objFeat->X.getValue(); objFeat->X.setValue(x); } void CreateTechDrawCommandsDims(void) { Gui::CommandManager &rcCmdMgr = Gui::Application::Instance->commandManager(); rcCmdMgr.addCommand(new CmdTechDrawNewDimension()); rcCmdMgr.addCommand(new CmdTechDrawNewRadiusDimension()); rcCmdMgr.addCommand(new CmdTechDrawNewDiameterDimension()); rcCmdMgr.addCommand(new CmdTechDrawNewLengthDimension()); rcCmdMgr.addCommand(new CmdTechDrawNewDistanceXDimension()); rcCmdMgr.addCommand(new CmdTechDrawNewDistanceYDimension()); rcCmdMgr.addCommand(new CmdTechDrawNewAngleDimension()); } //=========================================================================== // Selection Validation Helpers //=========================================================================== //! common checks of Selection for Dimension commands bool _checkSelection(Gui::Command* cmd) { std::vector selection = cmd->getSelection().getSelectionEx(); if (selection.size() == 0) { QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Incorrect selection"), QObject::tr("Select an object first")); return false; } TechDraw::DrawViewPart * objFeat = dynamic_cast(selection[0].getObject()); if(!objFeat) { QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Incorrect selection"), QObject::tr("No Feature in selection")); return false; } const std::vector &SubNames = selection[0].getSubNames(); if (SubNames.size() != 1 && SubNames.size() != 2){ QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Incorrect selection"), QObject::tr("Wrong number of objects selected")); return false; } std::vector pages = cmd->getDocument()->getObjectsOfType(TechDraw::DrawPage::getClassTypeId()); if (pages.empty()){ QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Incorrect selection"), QObject::tr("Create a page to insert.")); return false; } return true; } //! verify that Selection contains a valid Geometry for a single Edge Dimension (True or Projected) int _isValidSingleEdge(Gui::Command* cmd, bool trueDim) { int edgeType = isInvalid; std::vector selection = cmd->getSelection().getSelectionEx(); TechDraw::DrawViewPart * objFeat = dynamic_cast(selection[0].getObject()); const std::vector &SubNames = selection[0].getSubNames(); if (SubNames.size() == 1) { //only 1 subshape selected if (DrawUtil::getGeomTypeFromName(SubNames[0]) == "Edge") { //the Name starts with "Edge" int GeoId = DrawUtil::getIndexFromName(SubNames[0]); TechDrawGeometry::BaseGeom* geom = NULL; if (trueDim) { int ref = objFeat->getEdgeRefByIndex(GeoId); geom = objFeat->getCompleteEdge(ref); //project edge onto its shape to get 2D geom } else { geom = objFeat->getProjEdgeByIndex(GeoId); } if (!geom) { Base::Console().Error("Logic Error: no geometry for GeoId: %d\n",GeoId); return isInvalid; } if(geom->geomType == TechDrawGeometry::GENERIC) { TechDrawGeometry::Generic* gen1 = static_cast(geom); if(gen1->points.size() > 2) { //the edge is a polyline return isInvalid; } Base::Vector2D line = gen1->points.at(1) - gen1->points.at(0); if(fabs(line.fY) < FLT_EPSILON ) { edgeType = isHorizontal; } else if(fabs(line.fX) < FLT_EPSILON) { edgeType = isVertical; } else { edgeType = isDiagonal; } } else if (geom->geomType == TechDrawGeometry::CIRCLE || geom->geomType == TechDrawGeometry::ELLIPSE || geom->geomType == TechDrawGeometry::ARCOFCIRCLE || geom->geomType == TechDrawGeometry::ARCOFELLIPSE ) { edgeType = isCircle; } else if (geom->geomType == TechDrawGeometry::BSPLINE) { edgeType = isCurve; } else { edgeType = isInvalid; } } } return edgeType; } //! verify that Selection contains valid geometries for a Vertex to Vertex Dimension bool _isValidVertexes(Gui::Command* cmd) { std::vector selection = cmd->getSelection().getSelectionEx(); const std::vector &SubNames = selection[0].getSubNames(); if(SubNames.size() == 2) { //there are 2 if (DrawUtil::getGeomTypeFromName(SubNames[0]) == "Vertex" && //they both start with "Vertex" DrawUtil::getGeomTypeFromName(SubNames[1]) == "Vertex") { return true; } } return false; } //! verify that the Selection contains valid geometries for an Edge to Edge Dimension int _isValidEdgeToEdge(Gui::Command* cmd, bool trueDim) { //TODO: can the edges be in 2 different features?? int edgeType = isInvalid; std::vector selection = cmd->getSelection().getSelectionEx(); TechDraw::DrawViewPart* objFeat0 = dynamic_cast(selection[0].getObject()); //TechDraw::DrawViewPart* objFeat1 = dynamic_cast(selection[1].getObject()); const std::vector &SubNames = selection[0].getSubNames(); if(SubNames.size() == 2) { //there are 2 if (DrawUtil::getGeomTypeFromName(SubNames[0]) == "Edge" && //they both start with "Edge" DrawUtil::getGeomTypeFromName(SubNames[1]) == "Edge") { int GeoId0 = DrawUtil::getIndexFromName(SubNames[0]); int GeoId1 = DrawUtil::getIndexFromName(SubNames[1]); TechDrawGeometry::BaseGeom* geom0 = NULL; TechDrawGeometry::BaseGeom* geom1 = NULL; if (trueDim) { int ref0 = objFeat0->getEdgeRefByIndex(GeoId0); int ref1 = objFeat0->getEdgeRefByIndex(GeoId1); geom0 = objFeat0->getCompleteEdge(ref0); geom1 = objFeat0->getCompleteEdge(ref1); } else { geom0 = objFeat0->getProjEdgeByIndex(GeoId0); geom1 = objFeat0->getProjEdgeByIndex(GeoId1); } if ((!geom0) || (!geom1)) { Base::Console().Error("Logic Error: no geometry for GeoId: %d or GeoId: %d\n",GeoId0,GeoId1); return isInvalid; } if(geom0->geomType == TechDrawGeometry::GENERIC && geom1->geomType == TechDrawGeometry::GENERIC) { TechDrawGeometry::Generic *gen0 = static_cast(geom0); TechDrawGeometry::Generic *gen1 = static_cast(geom1); if(gen0->points.size() > 2 || gen1->points.size() > 2) { //the edge is a polyline return isInvalid; } Base::Vector2D line0 = gen0->points.at(1) - gen0->points.at(0); Base::Vector2D line1 = gen1->points.at(1) - gen1->points.at(0); double xprod = fabs(line0.fX * line1.fY - line0.fY * line1.fX); if(xprod > FLT_EPSILON) { //edges are not parallel return isAngle; } if(fabs(line0.fX) < FLT_EPSILON && fabs(line1.fX) < FLT_EPSILON) { edgeType = isHorizontal; } else if(fabs(line0.fY) < FLT_EPSILON && fabs(line1.fY) < FLT_EPSILON) { edgeType = isVertical; } else { edgeType = isDiagonal; } } else { return isInvalid; } } } return edgeType; } //! verify that each SubName has a corresponding Edge geometry in objFeat->Source bool _isTrueAllowed(TechDraw::DrawViewPart* objFeat, const std::vector &SubNames) { std::vector::const_iterator it = SubNames.begin(); bool trueDimAllowed = true; for (; it != SubNames.end(); it++) { int idx = DrawUtil::getIndexFromName((*it)); int ref = objFeat->getEdgeRefByIndex(idx); if (ref < 0) { trueDimAllowed = false; } } return trueDimAllowed; }