diff --git a/src/Mod/TechDraw/App/AppTechDraw.cpp b/src/Mod/TechDraw/App/AppTechDraw.cpp index d1b33c8e4f..a7980c8486 100644 --- a/src/Mod/TechDraw/App/AppTechDraw.cpp +++ b/src/Mod/TechDraw/App/AppTechDraw.cpp @@ -27,6 +27,7 @@ #include "DrawViewSection.h" #include "DrawViewAnnotation.h" #include "DrawViewDimension.h" +#include "DrawViewDimExtent.h" #include "DrawProjGroupItem.h" #include "DrawProjGroup.h" #include "DrawViewSymbol.h" @@ -86,6 +87,7 @@ PyMOD_INIT_FUNC(TechDraw) TechDraw::DrawViewSection ::init(); TechDraw::DrawViewMulti ::init(); TechDraw::DrawViewDimension ::init(); + TechDraw::DrawViewDimExtent ::init(); TechDraw::DrawProjGroup ::init(); TechDraw::DrawProjGroupItem ::init(); TechDraw::DrawViewDetail ::init(); diff --git a/src/Mod/TechDraw/App/AppTechDrawPy.cpp b/src/Mod/TechDraw/App/AppTechDrawPy.cpp index 513b8602f0..fa6716c685 100644 --- a/src/Mod/TechDraw/App/AppTechDrawPy.cpp +++ b/src/Mod/TechDraw/App/AppTechDrawPy.cpp @@ -70,7 +70,7 @@ #include "DrawUtil.h" #include "DrawProjGroup.h" #include "DrawProjGroupItem.h" - +#include "DrawDimHelper.h" namespace TechDraw { //module level static C++ functions go here @@ -113,6 +113,16 @@ public: add_varargs_method("findCentroid",&Module::findCentroid, "vector = findCentroid(shape,direction): finds geometric centroid of shape looking in direction." ); + add_varargs_method("makeExtentDim",&Module::makeExtentDim, + "makeExtentDim(DrawViewPart, [edges], direction) -- draw horizontal or vertical extent dimension for edges (or all of DrawViewPart if edge list is empty. direction: 0 - Horizontal, 1 - Vertical." + ); + add_varargs_method("makeDistanceDim",&Module::makeDistanceDim, + "makeDistanceDim(DrawViewPart, dimType, fromPoint, toPoint) -- draw a Length dimension between fromPoint to toPoint. FromPoint and toPoint are unscaled 2d View points. dimType is one of ['Distance', 'DistanceX', 'DistanceY'." + ); + add_varargs_method("makeDistanceDim3d",&Module::makeDistanceDim3d, + "makeDistanceDim(DrawViewPart, dimType, 3dFromPoint, 3dToPoint) -- draw a Length dimension between fromPoint to toPoint. FromPoint and toPoint are unscaled 3d model points. dimType is one of ['Distance', 'DistanceX', 'DistanceY'." + ); + initialize("This is a module for making drawings"); // register with Python } virtual ~Module() {} @@ -172,7 +182,7 @@ private: } } catch (Standard_Failure& e) { - + throw Py::Exception(Part::PartExceptionOCCError, e.GetMessageString()); } @@ -230,7 +240,7 @@ private: } } catch (Standard_Failure& e) { - + throw Py::Exception(Part::PartExceptionOCCError, e.GetMessageString()); } @@ -294,7 +304,7 @@ private: edgeList = DrawProjectSplit::getEdgesForWalker(shape,scale,dir); } catch (Standard_Failure& e) { - + throw Py::Exception(Part::PartExceptionOCCError, e.GetMessageString()); } @@ -333,14 +343,14 @@ private: PyObject *viewObj; if (!PyArg_ParseTuple(args.ptr(), "O", &viewObj)) { throw Py::TypeError("expected (DrawViewPart)"); - } + } Py::String dxfReturn; try { App::DocumentObject* obj = 0; TechDraw::DrawViewPart* dvp = 0; Drawing::DXFOutput dxfOut; - std::string dxfText; + std::string dxfText; std::stringstream ss; if (PyObject_TypeCheck(viewObj, &(TechDraw::DrawViewPartPy::Type))) { obj = static_cast(viewObj)->getDocumentObjectPtr(); @@ -388,7 +398,7 @@ private: PyObject *viewObj; if (!PyArg_ParseTuple(args.ptr(), "O", &viewObj)) { throw Py::TypeError("expected (DrawViewPart)"); - } + } Py::String svgReturn; std::string grpHead1 = "\n"; @@ -397,7 +407,7 @@ private: App::DocumentObject* obj = 0; TechDraw::DrawViewPart* dvp = 0; Drawing::SVGOutput svgOut; - std::string svgText; + std::string svgText; std::stringstream ss; if (PyObject_TypeCheck(viewObj, &(TechDraw::DrawViewPartPy::Type))) { obj = static_cast(viewObj)->getDocumentObjectPtr(); @@ -488,7 +498,7 @@ private: gp_Trsf xLate; xLate.SetTranslation(gp_Vec(dvpX,dvpY,0.0)); BRepBuilderAPI_Transform mkTrf(s, xLate); - s = mkTrf.Shape(); + s = mkTrf.Shape(); writer.exportShape(s); s = TechDraw::mirrorShape(go->getVisOutline()); mkTrf.Perform(s); @@ -529,7 +539,7 @@ private: writer.exportShape(s); } } - + Py::Object writeDXFView(const Py::Tuple& args) { PyObject *viewObj; @@ -537,8 +547,8 @@ private: PyObject *alignObj = Py_True; if (!PyArg_ParseTuple(args.ptr(), "Oet|O", &viewObj, "utf-8",&name,&alignObj)) { throw Py::TypeError("expected (view,path"); - } - + } + std::string filePath = std::string(name); std::string layerName = "none"; PyMem_Free(name); @@ -557,7 +567,7 @@ private: if (PyObject_TypeCheck(viewObj, &(TechDraw::DrawViewPartPy::Type))) { obj = static_cast(viewObj)->getDocumentObjectPtr(); dvp = static_cast(obj); - + layerName = dvp->getNameInDocument(); writer.setLayerName(layerName); write1ViewDxf(writer,dvp,align); @@ -578,7 +588,7 @@ private: if (!PyArg_ParseTuple(args.ptr(), "Oet", &pageObj, "utf-8",&name)) { throw Py::TypeError("expected (page,path"); } - + std::string filePath = std::string(name); std::string layerName = "none"; PyMem_Free(name); @@ -644,9 +654,9 @@ private: Base::Vector3d norm(-dimLine.y,dimLine.x,0.0); norm.Normalize(); lineLocn = lineLocn + (norm * gap); - Base::Vector3d extLine1Start = Base::Vector3d(pts.first.x,-pts.first.y,0.0) + + Base::Vector3d extLine1Start = Base::Vector3d(pts.first.x,-pts.first.y,0.0) + Base::Vector3d(parentX,parentY,0.0); - Base::Vector3d extLine2Start = Base::Vector3d(pts.second.x, -pts.second.y, 0.0) + + Base::Vector3d extLine2Start = Base::Vector3d(pts.second.x, -pts.second.y, 0.0) + Base::Vector3d(parentX,parentY,0.0); writer.exportLinearDim(textLocn, lineLocn, extLine1Start, extLine2Start, dimText); } else if (dvd->Type.isValue("Angle")) { @@ -733,9 +743,118 @@ private: return Py::asObject(result); } + Py::Object makeExtentDim(const Py::Tuple& args) + { + PyObject* pDvp; + PyObject* pEdgeList; + int direction = 0; //Horizontal + TechDraw::DrawViewPart* dvp = nullptr; + + if (!PyArg_ParseTuple(args.ptr(), "OO!i", &pDvp, &(PyList_Type), &pEdgeList, &direction)) { + throw Py::TypeError("expected (DrawViewPart, listofedgesnames, direction"); + } + if (PyObject_TypeCheck(pDvp, &(TechDraw::DrawViewPartPy::Type))) { + App::DocumentObject* obj = static_cast(pDvp)->getDocumentObjectPtr(); + dvp = static_cast(obj); + } + + std::vector edgeList; + try { + Py::Sequence list(pEdgeList); + for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) { + if (PyUnicode_Check((*it).ptr())) { + std::string temp = PyUnicode_AsUTF8((*it).ptr()); + edgeList.push_back(temp); + } + } + } + catch (Standard_Failure& e) { + + throw Py::Exception(Part::PartExceptionOCCError, e.GetMessageString()); + } + + DrawDimHelper::makeExtentDim(dvp, + edgeList, + direction); + return Py::None(); + } + + Py::Object makeDistanceDim(const Py::Tuple& args) + { + PyObject* pDvp; + PyObject* pDimType; + PyObject* pFrom; + PyObject* pTo; + TechDraw::DrawViewPart* dvp = nullptr; + std::string dimType; + Base::Vector3d from; + Base::Vector3d to; + + if (!PyArg_ParseTuple(args.ptr(), "OOOO", &pDvp, &pDimType, &pFrom, &pTo)) { + throw Py::TypeError("expected (DrawViewPart, dimType, from, to"); + } + //TODO: errors for all the type checks + if (PyObject_TypeCheck(pDvp, &(TechDraw::DrawViewPartPy::Type))) { + App::DocumentObject* obj = static_cast(pDvp)->getDocumentObjectPtr(); + dvp = static_cast(obj); + } + if (PyUnicode_Check(pDimType)) { + dimType = PyUnicode_AsUTF8(pDimType); + } + if (PyObject_TypeCheck(pFrom, &(Base::VectorPy::Type))) { + from = static_cast(pFrom)->value(); + } + if (PyObject_TypeCheck(pTo, &(Base::VectorPy::Type))) { + to = static_cast(pTo)->value(); + } + DrawDimHelper::makeDistDim(dvp, + dimType, + from, + to); + + return Py::None(); + } + + Py::Object makeDistanceDim3d(const Py::Tuple& args) + { + PyObject* pDvp; + PyObject* pDimType; + PyObject* pFrom; + PyObject* pTo; + TechDraw::DrawViewPart* dvp = nullptr; + std::string dimType; + Base::Vector3d from; + Base::Vector3d to; + + if (!PyArg_ParseTuple(args.ptr(), "OOOO", &pDvp, &pDimType, &pFrom, &pTo)) { + throw Py::TypeError("expected (DrawViewPart, dimType, from, to"); + } + //TODO: errors for all the type checks + if (PyObject_TypeCheck(pDvp, &(TechDraw::DrawViewPartPy::Type))) { + App::DocumentObject* obj = static_cast(pDvp)->getDocumentObjectPtr(); + dvp = static_cast(obj); + } + if (PyUnicode_Check(pDimType)) { + dimType = PyUnicode_AsUTF8(pDimType); + } + if (PyObject_TypeCheck(pFrom, &(Base::VectorPy::Type))) { + from = static_cast(pFrom)->value(); + } + if (PyObject_TypeCheck(pTo, &(Base::VectorPy::Type))) { + to = static_cast(pTo)->value(); + } + from = DrawUtil::invertY(dvp->projectPoint(from)); + to = DrawUtil::invertY(dvp->projectPoint(to)); + DrawDimHelper::makeDistDim(dvp, + dimType, + from, + to); + + return Py::None(); + } }; -PyObject* initModule() + PyObject* initModule() { return (new Module)->module().ptr(); } diff --git a/src/Mod/TechDraw/App/CMakeLists.txt b/src/Mod/TechDraw/App/CMakeLists.txt index f1787642f5..d6fe80db2e 100644 --- a/src/Mod/TechDraw/App/CMakeLists.txt +++ b/src/Mod/TechDraw/App/CMakeLists.txt @@ -51,6 +51,7 @@ generate_from_xml(DrawSVGTemplatePy) generate_from_xml(DrawViewSymbolPy) generate_from_xml(DrawViewClipPy) generate_from_xml(DrawViewDimensionPy) +generate_from_xml(DrawViewDimExtentPy) generate_from_xml(DrawHatchPy) generate_from_xml(DrawGeomHatchPy) generate_from_xml(DrawViewCollectionPy) @@ -96,6 +97,8 @@ SET(Draw_SRCS DrawViewCollection.h DrawViewDimension.cpp DrawViewDimension.h + DrawViewDimExtent.cpp + DrawViewDimExtent.h DrawViewBalloon.cpp DrawViewBalloon.h DrawViewSection.cpp @@ -135,6 +138,8 @@ SET(TechDraw_SRCS DrawUtil.h ShapeExtractor.cpp ShapeExtractor.h + DrawDimHelper.cpp + DrawDimHelper.h HatchLine.cpp HatchLine.h PreCompiled.cpp @@ -183,6 +188,8 @@ SET(Python_SRCS DrawViewClipPyImp.cpp DrawViewDimensionPy.xml DrawViewDimensionPyImp.cpp + DrawViewDimExtentPy.xml + DrawViewDimExtentPyImp.cpp DrawHatchPy.xml DrawHatchPyImp.cpp DrawGeomHatchPy.xml diff --git a/src/Mod/TechDraw/App/Cosmetic.cpp b/src/Mod/TechDraw/App/Cosmetic.cpp index 0d89a8c14a..fb4417e7db 100644 --- a/src/Mod/TechDraw/App/Cosmetic.cpp +++ b/src/Mod/TechDraw/App/Cosmetic.cpp @@ -140,22 +140,30 @@ CosmeticVertex::CosmeticVertex() : TechDraw::Vertex() App::Color fcColor; fcColor.setPackedValue(hGrp->GetUnsigned("VertexColor", 0x00000000)); + permaPoint = Base::Vector3d(0.0, 0.0, 0.0); linkGeom = -1; color = fcColor; size = 3.0; style = 1; visible = true; + //TODO: sort out 2x visible variables + Vertex::visible = true; //yuck + cosmetic = true; + createNewTag(); } CosmeticVertex::CosmeticVertex(const TechDraw::CosmeticVertex* cv) : TechDraw::Vertex(cv) { + permaPoint = cv->permaPoint; linkGeom = cv->linkGeom; color = cv->color; size = cv->size; style = cv->style; visible = cv->visible; + Vertex::visible = true; //yuck + cosmetic = true; createNewTag(); } @@ -167,12 +175,15 @@ CosmeticVertex::CosmeticVertex(Base::Vector3d loc) : TechDraw::Vertex(loc) App::Color fcColor; fcColor.setPackedValue(hGrp->GetUnsigned("VertexColor", 0xff000000)); + permaPoint = loc; linkGeom = -1; color = fcColor; //TODO: size = hGrp->getFloat("VertexSize",30.0); size = 30.0; style = 1; //TODO: implement styled vertexes visible = true; + Vertex::visible = true; //yuck + cosmetic = true; createNewTag(); @@ -181,14 +192,22 @@ CosmeticVertex::CosmeticVertex(Base::Vector3d loc) : TechDraw::Vertex(loc) std::string CosmeticVertex::toString(void) const { std::stringstream ss; + ss << permaPoint.x << "," << + permaPoint.y << "," << + permaPoint.z << "," << + " / "; ss << point().x << "," << point().y << "," << point().z << "," << - - linkGeom << "," << + " / " << + linkGeom << "," << + " / " << color.asHexString() << "," << + " / " << size << "," << + " / " << style << "," << + " / " << visible; return ss.str(); } @@ -202,6 +221,11 @@ unsigned int CosmeticVertex::getMemSize (void) const void CosmeticVertex::Save(Base::Writer &writer) const { TechDraw::Vertex::Save(writer); + writer.Stream() << writer.ind() << "" << endl; writer.Stream() << writer.ind() << "" << endl; writer.Stream() << writer.ind() << "" << endl; writer.Stream() << writer.ind() << "" << endl; @@ -213,6 +237,10 @@ void CosmeticVertex::Save(Base::Writer &writer) const void CosmeticVertex::Restore(Base::XMLReader &reader) { TechDraw::Vertex::Restore(reader); + reader.readElement("PermaPoint"); + permaPoint.x = reader.getAttributeAsFloat("X"); + permaPoint.y = reader.getAttributeAsFloat("Y"); + permaPoint.z = reader.getAttributeAsFloat("Z"); reader.readElement("LinkGeom"); linkGeom = reader.getAttributeAsInteger("value"); reader.readElement("Color"); @@ -226,6 +254,12 @@ void CosmeticVertex::Restore(Base::XMLReader &reader) visible = (int)reader.getAttributeAsInteger("value")==0?false:true; } +Base::Vector3d CosmeticVertex::scaled(double factor) +{ + pnt = permaPoint * factor; + return pnt; +} + boost::uuids::uuid CosmeticVertex::getTag() const { return tag; diff --git a/src/Mod/TechDraw/App/Cosmetic.h b/src/Mod/TechDraw/App/Cosmetic.h index 8e1dc297ab..0f7074d619 100644 --- a/src/Mod/TechDraw/App/Cosmetic.h +++ b/src/Mod/TechDraw/App/Cosmetic.h @@ -23,7 +23,7 @@ #ifndef TECHDRAW_COSMETIC_H #define TECHDRAW_COSMETIC_H -# include +#include #include #include @@ -77,6 +77,7 @@ public: std::string toString(void) const; /* bool fromCSV(std::string& lineSpec);*/ void dump(char* title); + Base::Vector3d scaled(double factor); // Persistence implementer --------------------- virtual unsigned int getMemSize(void) const; @@ -87,14 +88,15 @@ public: CosmeticVertex* copy(void) const; CosmeticVertex* clone(void) const; - int linkGeom; //connection to corresponding "real" Vertex + Base::Vector3d permaPoint; //permanent, unscaled value + int linkGeom; //connection to corresponding "geom" Vertex App::Color color; double size; int style; - bool visible; + bool visible; //base class vertex also has visible property boost::uuids::uuid getTag() const; - std::string getTagAsString(void) const; + virtual std::string getTagAsString(void) const; protected: diff --git a/src/Mod/TechDraw/App/DrawDimHelper.cpp b/src/Mod/TechDraw/App/DrawDimHelper.cpp new file mode 100644 index 0000000000..a6830eac55 --- /dev/null +++ b/src/Mod/TechDraw/App/DrawDimHelper.cpp @@ -0,0 +1,381 @@ +/*************************************************************************** + * Copyright (c) 2019 WandererFan * + * * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "Geometry.h" +#include "DrawUtil.h" +#include "Cosmetic.h" +#include "DrawPage.h" +#include "DrawViewPart.h" +#include "DrawViewDimension.h" +#include "DrawViewDimExtent.h" + +#include "DrawDimHelper.h" + +#define HORIZONTAL 0 +#define VERTICAL 1 +#define LENGTH 2 + +using namespace TechDraw; + +hTrimCurve::hTrimCurve(Handle(Geom2d_Curve) hCurveIn, + double parm1, + double parm2) : + hCurve(hCurveIn), + first(parm1), + last(parm2) +{ + //just a convenient struct for now. +} + +//All this occ math is being done on on edges(&vertices) that have been through the center/scale/mirror process. + +//TODO: this needs to be exposed to Python +void DrawDimHelper::makeExtentDim(DrawViewPart* dvp, + std::vector edgeNames, + int direction) +{ +// Base::Console().Message("DDH::makeExtentDim() - dvp: %s edgeNames: %d\n", +// dvp->Label.getValue(), edgeNames.size()); + if (dvp == nullptr) { +// Base::Console().Message("DDH::makeExtentDim - dvp: %X\n", dvp); + return; + } + + std::string dimType = "DistanceX"; + int dimNum = 0; + if (direction == VERTICAL) { + dimType = "DistanceY"; + dimNum = 1; + } + + std::pair endPoints = minMax(dvp, + edgeNames, + direction); + Base::Vector3d refMin = endPoints.first; + Base::Vector3d refMax = endPoints.second; + + //pause recomputes + dvp->getDocument()->setStatus(App::Document::Status::SkipRecompute, true); + + DrawViewDimension* distDim = makeDistDim(dvp, dimType, refMin, refMax, true); + std::string dimName = distDim->getNameInDocument(); + Base::Interpreter().runStringArg("App.activeDocument().%s.DirExtent = %d", + dimName.c_str(), dimNum); + DrawViewDimExtent* extDim = dynamic_cast(distDim); + extDim->Source.setValue(dvp, edgeNames); + + //continue recomputes + dvp->getDocument()->setStatus(App::Document::Status::SkipRecompute, false); + extDim->recomputeFeature(); +} + +std::pair DrawDimHelper::minMax(DrawViewPart* dvp, + std::vector edgeNames, + int direction) +{ +// Base::Console().Message("DDH::minMax()\n"); + std::pair result; + Base::Vector3d refMin; + Base::Vector3d refMax; + + gp_Pnt stdOrg(0.0, 0.0, 0.0); + gp_Dir stdZ(0.0, 0.0, 1.0); + gp_Dir stdX(1.0, 0.0, 0.0); + gp_Ax3 projAx3(stdOrg, stdZ, stdX); + gp_Pln projPlane(projAx3); // OZX + + std::vector bgList; + if (!edgeNames.empty()) { + for (auto& n: edgeNames) { + if (!n.empty()) { + std::string geomType = DrawUtil::getGeomTypeFromName(n); + if (!n.empty() && (geomType == "Edge")) { + int i = DrawUtil::getIndexFromName(n); + BaseGeom* bg = dvp->getGeomByIndex(i); + if (bg != nullptr) { + bgList.push_back(bg); + } + } + } + } + } + + std::vector selEdges = bgList; + if (selEdges.empty()) { + selEdges = dvp->getEdgeGeometry(); //do the whole View + } + + std::vector selCurves; + std::vector hTCurve2dList; + for (auto& bg: selEdges) { + TopoDS_Edge e = bg->occEdge; + double first = 0.0; + double last = 0.0; + Handle(Geom_Curve) hCurve = BRep_Tool::Curve(e, first, last); + Handle(Geom2d_Curve) hCurve2 = GeomAPI::To2d (hCurve, projPlane); + hTrimCurve temp(hCurve2, first, last); + hTCurve2dList.push_back(temp); + } + + //can't use Bnd_Box2d here as BndLib_Add2dCurve::Add adds the poles of splines to the box. + //poles are not neccessarily on the curve! 3d Bnd_Box does it properly. FC bbx3 is already calculated + //bbx3 is scaled?? +// double scale = dvp->getScale(); + + Base::BoundBox3d bbx3 = dvp->getBoundingBox(); + + double xMid = (bbx3.MaxX + bbx3.MinX) / 2.0; + double yMid = (bbx3.MaxY + bbx3.MinY) / 2.0; + + gp_Pnt2d rightMid(bbx3.MaxX, yMid); + gp_Pnt2d leftMid(bbx3.MinX, yMid); + gp_Pnt2d topMid(xMid, bbx3.MaxY); + gp_Pnt2d bottomMid(xMid, bbx3.MinY); + gp_Dir2d xDir(1.0, 0.0); + gp_Dir2d yDir(0.0, 1.0); + + if (direction == HORIZONTAL) { + Handle(Geom2d_Line) boundaryLeft = new Geom2d_Line(leftMid, yDir); + gp_Pnt2d leftPoint = findClosestPoint(hTCurve2dList, + boundaryLeft); + Handle(Geom2d_Line) boundaryRight = new Geom2d_Line(rightMid, yDir); + gp_Pnt2d rightPoint = findClosestPoint(hTCurve2dList, + boundaryRight); + + refMin = Base::Vector3d(leftPoint.X(), leftPoint.Y(), 0.0); + refMax = Base::Vector3d(rightPoint.X(), rightPoint.Y(), 0.0); + + } else if (direction == VERTICAL) { + Handle(Geom2d_Line) boundaryBottom = new Geom2d_Line(bottomMid, xDir); + gp_Pnt2d bottomPoint = findClosestPoint(hTCurve2dList, + boundaryBottom); + Handle(Geom2d_Line) boundaryTop = new Geom2d_Line(topMid, xDir); + gp_Pnt2d topPoint = findClosestPoint(hTCurve2dList, + boundaryTop); + refMin = Base::Vector3d(bottomPoint.X(),bottomPoint.Y(), 0.0); + refMax = Base::Vector3d(topPoint.X(), topPoint.Y(), 0.0); + } + + result.first = refMin; + result.second = refMax; + return result; +} + +//given list of curves, find the closest point from any curve to a boundary +//computation intensive for a cosmetic result. +gp_Pnt2d DrawDimHelper::findClosestPoint(std::vector hTCurve2dList, + Handle(Geom2d_Curve) boundary) +{ +// Base::Console().Message("DDH::findClosestPoint() - curves: %d\n", hTCurve2dList.size()); +// +//find an extent point that is actually on one of the curves + gp_Pnt2d result(-1.0, -1.0); + Geom2dAdaptor_Curve aBoundary(boundary); + + double globalNearDist = FLT_MAX; + gp_Pnt2d globalNearPoint; + bool found = false; + for (auto& hCurve2d : hTCurve2dList) { + Geom2dAdaptor_Curve aCurve(hCurve2d.hCurve, + hCurve2d.first, + hCurve2d.last); + Extrema_ExtCC2d mkExtr(aBoundary, aCurve); + if (mkExtr.IsDone()) { + double nearDist = FLT_MAX; + int nearIdx = 0; + gp_Pnt2d nearPoint; + if (mkExtr.NbExt() > 0) { + int stop = mkExtr.NbExt(); + int i = 1; //this is OCC start (1) not conventional start (0) + for ( ; i <= stop; i++) { + double dist = mkExtr.SquareDistance(i); + if (dist < nearDist) { + found = true; + nearDist = dist; + nearIdx = i; + Extrema_POnCurv2d p1, p2; + mkExtr.Points(nearIdx, p1, p2); + nearPoint = p2.Value(); + } + } + } else { //no extrema? - might be a line parallel to boundary + if (mkExtr.IsParallel()) { + //get midpoint of aCurve + double mid = (hCurve2d.first + hCurve2d.last) / 2.0; + gp_Pnt2d midPoint = hCurve2d.hCurve->Value(mid); + //get distance midpoint to boundary => nearDist + Geom2dAPI_ProjectPointOnCurve mkProj(midPoint, boundary); + double dist = mkProj.LowerDistance() * mkProj.LowerDistance(); + if (dist < nearDist) { + found = true; + nearDist = dist; + nearPoint = mkProj.NearestPoint(); + } + } else { //skew and no extrema? + gp_Pnt2d pFirst = hCurve2d.hCurve->Value(hCurve2d.first); + Geom2dAPI_ProjectPointOnCurve mkFirst(pFirst, boundary); + double dist1 = mkFirst.LowerDistance() * mkFirst.LowerDistance(); + gp_Pnt2d pLast = hCurve2d.hCurve->Value(hCurve2d.last); + Geom2dAPI_ProjectPointOnCurve mkLast(pLast, boundary); + double dist2 = mkLast.LowerDistance() * mkLast.LowerDistance(); + if (dist1 < dist2) { + if (dist1 < nearDist) { + found = true; + nearDist = dist1; + nearPoint = mkFirst.NearestPoint(); + } + } else { + if (dist2 < nearDist) { + found = true; + nearDist = dist2; + nearPoint = mkLast.NearestPoint(); + } + } + } + } + if (nearDist < globalNearDist) { + globalNearDist = nearDist; + globalNearPoint = nearPoint; + } + } + } + if (found) { + result = globalNearPoint; + } + + return result; +} + +//TODO: this needs to be exposed to Python +DrawViewDimension* DrawDimHelper::makeDistDim(DrawViewPart* dvp, + std::string dimType, + Base::Vector3d inMin, + Base::Vector3d inMax, + bool extent) +{ +// Base::Console().Message("DDH::makeDistDim() - inMin: %s inMax: %s\n", +// DrawUtil::formatVector(inMin).c_str(), +// DrawUtil::formatVector(inMax).c_str()); + TechDraw::DrawPage* page = dvp->findParentPage(); + std::string pageName = page->getNameInDocument(); + + double scale = dvp->getScale(); + + TechDraw::DrawViewDimension *dim = 0; + App::Document* doc = dvp->getDocument(); + std::string dimName = doc->getUniqueObjectName("Dimension"); + if (extent) { + dimName = doc->getUniqueObjectName("DimExtent"); + } + + Base::Vector3d cleanMin = DrawUtil::invertY(inMin) / scale; + int idx1 = dvp->addCosmeticVertex(cleanMin); //CV index + dvp->add1CVToGV(idx1); + Base::Vector3d cleanMax = DrawUtil::invertY(inMax) / scale; + int idx2 = dvp->addCosmeticVertex(cleanMax); + dvp->add1CVToGV(idx2); + + CosmeticVertex* cv1 = dvp->getCosmeticVertexByIndex(idx1); + CosmeticVertex* cv2 = dvp->getCosmeticVertexByIndex(idx2); + int iGV1 = cv1->linkGeom; + int iGV2 = cv2->linkGeom; + + std::vector objs; + std::vector subs; + + std::stringstream ss; + ss << "Vertex" << iGV1; + std::string vertexName = ss.str(); + subs.push_back(vertexName); + objs.push_back(dvp); + + ss.clear(); + ss.str(""); + ss << "Vertex" << iGV2; + vertexName = ss.str(); + subs.push_back(vertexName); + objs.push_back(dvp); + + if (extent) { + Base::Interpreter().runStringArg("App.activeDocument().addObject('TechDraw::DrawViewDimExtent','%s')", + dimName.c_str()); + } else { + + Base::Interpreter().runStringArg("App.activeDocument().addObject('TechDraw::DrawViewDimension','%s')", + dimName.c_str()); + } + Base::Interpreter().runStringArg("App.activeDocument().%s.Type = '%s'", + dimName.c_str(), dimType.c_str()); + Base::Interpreter().runStringArg("App.activeDocument().%s.addView(App.activeDocument().%s)", + pageName.c_str(),dimName.c_str()); + + + dim = dynamic_cast(doc->getObject(dimName.c_str())); + if (!dim) { + throw Base::TypeError("DDH::makeDistDim - dim not found\n"); + } + + dim->References2D.setValues(objs, subs); + + dvp->requestPaint(); + dim->recomputeFeature(); + + return dim; +} + diff --git a/src/Mod/TechDraw/App/DrawDimHelper.h b/src/Mod/TechDraw/App/DrawDimHelper.h new file mode 100644 index 0000000000..6dbc41a399 --- /dev/null +++ b/src/Mod/TechDraw/App/DrawDimHelper.h @@ -0,0 +1,73 @@ +/*************************************************************************** + * Copyright (c) 2019 WandererFan * + * * + * 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 _DrawDimHelper_h_ +#define _DrawDimHelper_h_ + +#include + +#include +#include + +class gp_Pnt2d; +class Geom2d_Curve; + +namespace TechDraw +{ +class BaseGeom; +class DrawViewPart; + +class TechDrawExport hTrimCurve { + public: + hTrimCurve() {} + hTrimCurve(Handle(Geom2d_Curve) hCurveIn, + double parm1, + double parm2); + ~hTrimCurve() {} + + Handle(Geom2d_Curve) hCurve; + double first; + double last; +}; + + +/// Additional functions for working with Dimensions +class TechDrawExport DrawDimHelper { + public: + static void makeExtentDim(DrawViewPart* dvp, +// std::vector selEdges, + std::vector edgeNames, + int direction); + static gp_Pnt2d findClosestPoint(std::vector hCurve2dList, + Handle(Geom2d_Curve) boundary); + static TechDraw::DrawViewDimension* makeDistDim(DrawViewPart* dvp, + std::string dimType, + Base::Vector3d refMin, + Base::Vector3d refMax, + bool extent = false); + static std::pair minMax(DrawViewPart* dvp, + std::vector edgeNames, + int direction); +}; + +} //end namespace TechDraw +#endif diff --git a/src/Mod/TechDraw/App/DrawUtil.cpp b/src/Mod/TechDraw/App/DrawUtil.cpp index b939df480d..a703b55c7a 100644 --- a/src/Mod/TechDraw/App/DrawUtil.cpp +++ b/src/Mod/TechDraw/App/DrawUtil.cpp @@ -309,6 +309,15 @@ std::string DrawUtil::formatVector(const gp_Dir& v) return result; } +std::string DrawUtil::formatVector(const gp_Dir2d& v) +{ + std::string result; + std::stringstream builder; + builder << std::fixed << std::setprecision(3) ; + builder << " (" << v.X() << "," << v.Y() << ") "; + result = builder.str(); + return result; +} std::string DrawUtil::formatVector(const gp_Vec& v) { std::string result; @@ -329,6 +338,16 @@ std::string DrawUtil::formatVector(const gp_Pnt& v) return result; } +std::string DrawUtil::formatVector(const gp_Pnt2d& v) +{ + std::string result; + std::stringstream builder; + builder << std::fixed << std::setprecision(3) ; + builder << " (" << v.X() << "," << v.Y() << ") "; + result = builder.str(); + return result; +} + std::string DrawUtil::formatVector(const QPointF& v) { std::string result; diff --git a/src/Mod/TechDraw/App/DrawUtil.h b/src/Mod/TechDraw/App/DrawUtil.h index a97b2fa5ce..d50e149f4a 100644 --- a/src/Mod/TechDraw/App/DrawUtil.h +++ b/src/Mod/TechDraw/App/DrawUtil.h @@ -31,7 +31,9 @@ #include #include +#include #include +#include #include #include #include @@ -80,8 +82,10 @@ class TechDrawExport DrawUtil { static Base::Vector3d vertex2Vector(const TopoDS_Vertex& v); static std::string formatVector(const Base::Vector3d& v); static std::string formatVector(const gp_Dir& v); + static std::string formatVector(const gp_Dir2d& v); static std::string formatVector(const gp_Vec& v); static std::string formatVector(const gp_Pnt& v); + static std::string formatVector(const gp_Pnt2d& v); static std::string formatVector(const QPointF& v); static bool vectorLess(const Base::Vector3d& v1, const Base::Vector3d& v2); diff --git a/src/Mod/TechDraw/App/DrawViewDimExtent.cpp b/src/Mod/TechDraw/App/DrawViewDimExtent.cpp new file mode 100644 index 0000000000..6da6cf1369 --- /dev/null +++ b/src/Mod/TechDraw/App/DrawViewDimExtent.cpp @@ -0,0 +1,218 @@ +/*************************************************************************** + * Copyright (c) 2019 Wandererfan * + * * + * 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 + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + + +#include "Geometry.h" +#include "DrawViewPart.h" +#include "DrawViewDimExtent.h" +#include "DrawDimHelper.h" +#include "DrawUtil.h" +#include "LineGroup.h" + +#include // generated from DrawViewDimExtentPy.xml + +using namespace TechDraw; + +//=========================================================================== +// DrawViewDimExtent +//=========================================================================== + +PROPERTY_SOURCE(TechDraw::DrawViewDimExtent, TechDraw::DrawViewDimension) + +DrawViewDimExtent::DrawViewDimExtent(void) +{ + App::PropertyLinkSubList Source; //DrawViewPart & SubElements(Edges) + //Cosmetic End points are stored in DVD::References2d + App::PropertyLinkSubList Source3d; //Part::Feature & SubElements TBI + + ADD_PROPERTY_TYPE(Source,(0,0),"",(App::PropertyType)(App::Prop_Output),"View (Edges) to dimension"); + Source.setScope(App::LinkScope::Global); + ADD_PROPERTY_TYPE(Source3d,(0,0),"",(App::PropertyType)(App::Prop_Output),"View (Edges) to dimension"); //TBI + Source3d.setScope(App::LinkScope::Global); + ADD_PROPERTY_TYPE(DirExtent ,(0),"",App::Prop_Output,"Horizontal / Vertical"); + + //hide the properties the user can't edit in the property editor + Source3d.setStatus(App::Property::Hidden,true); //TBI + +} + +DrawViewDimExtent::~DrawViewDimExtent() +{ +} + +void DrawViewDimExtent::onChanged(const App::Property* prop) +{ + if (!isRestoring()) { + if (prop == &Source) { +// Base::Console().Message("DVDE::onChanged - Source: %X\n", Source.getValue()); + //recalculate the points? + } + } + DrawViewDimension::onChanged(prop); +} + +short DrawViewDimExtent::mustExecute() const +{ + return DrawViewDimension::mustExecute(); +} + +App::DocumentObjectExecReturn *DrawViewDimExtent::execute(void) +{ +// Base::Console().Message("DVDE::execute() - %s\n", getNameInDocument()); + if (!keepUpdated()) { + return App::DocumentObject::StdReturn; + } + + App::DocumentObject* docObj = Source.getValue(); + if (docObj == nullptr) { + return App::DocumentObject::StdReturn; + } + DrawViewPart* dvp = dynamic_cast(docObj); + if (dvp == nullptr) { + return App::DocumentObject::StdReturn; + } + + double tolerance = 0.00001; + std::vector edgeNames = getSubNames(); + int direction = DirExtent.getValue(); + + std::pair endPoints = + DrawDimHelper::minMax(dvp, + edgeNames, + direction); + Base::Vector3d refMin = endPoints.first; + Base::Vector3d refMax = endPoints.second; + + TechDraw::Vertex* v0 = nullptr; + TechDraw::Vertex* v1 = nullptr; + const std::vector &subElements = References2D.getSubValues(); + if (subElements.size() > 1) { + int idx0 = DrawUtil::getIndexFromName(subElements[0]); + int idx1 = DrawUtil::getIndexFromName(subElements[1]); + v0 = getViewPart()->getProjVertexByIndex(idx0); + v1 = getViewPart()->getProjVertexByIndex(idx1); + + double length00 = (v0->pnt - refMin).Length(); + double length11 = (v1->pnt - refMax).Length(); + double length01 = (v0->pnt - refMax).Length(); + double length10 = (v1->pnt - refMin).Length(); + if ( ((length00 < tolerance) && + (length11 < tolerance)) || + ((length01 < tolerance) && + (length10 < tolerance)) ) { + } else { + //update GV + v0->pnt = refMin; + v1->pnt = refMax; + // v0->occVertex = ??? + // v1->occVertex = ??? + //update CV + double scale = dvp->getScale(); + int cv0 = v0->cosmeticLink; + CosmeticVertex* cvTemp = dvp->getCosmeticVertexByIndex(cv0); + cvTemp->permaPoint = refMin / scale; + int cv1 = v1->cosmeticLink; + cvTemp = dvp->getCosmeticVertexByIndex(cv1); + cvTemp->permaPoint = refMax / scale; + } + } + + return DrawViewDimension::execute(); +} + +//getSubValues returns a garbage 1st entry if there are no subelements. +std::vector DrawViewDimExtent::getSubNames(void) +{ + std::vector result; + std::vector edgeNames = Source.getSubValues(); + if (!edgeNames.empty() && + (edgeNames[0].size() == 0)) { + //garbage first entry - nop + } else { + result = edgeNames; + } + return result; +} + +void DrawViewDimExtent::unsetupObject() +{ + //CV's need to be deleted, but deleting messes up all the indices to other CV's! +// TechDraw::DrawViewPart* dvp = getViewPart(); +// std::vector cVerts = dvp->CosmeticVertexes.getValues(); +// Base::Console().Message("DVDE::unsetupObject() - cVerts: %d\n", cVerts.size()); +// TechDraw::Vertex* v0 = nullptr; +// TechDraw::Vertex* v1 = nullptr; +// const std::vector &subElements = References2D.getSubValues(); +// if (subElements.size() > 1) { +// Base::Console().Message("DVDE::unsetupObject - more than 1 subElement\n"); +// int idx1 = DrawUtil::getIndexFromName(subElements[1]); +// v1 = dvp->getProjVertexByIndex(idx1); +// if (v1 != nullptr) { +// int cv1 = v1->cosmeticLink; +// dvp->removeCosmeticVertex(cv1); +// } + +// int idx0 = DrawUtil::getIndexFromName(subElements[0]); +// v0 = dvp->getProjVertexByIndex(idx0); +// if (v0 != nullptr) { +// int cv0 = v0->cosmeticLink; +// dvp->removeCosmeticVertex(cv0); +// } +// } +// cVerts = dvp->CosmeticVertexes.getValues(); +// Base::Console().Message("DVDE::unsetupObject - exit - cVerts: %d\n", cVerts.size()); + DrawViewDimension::unsetupObject(); +// App::DocumentObject::unsetUpObject(); +} + +PyObject *DrawViewDimExtent::getPyObject(void) +{ + if (PythonObject.is(Py::_None())) { + // ref counter is set to 1 + PythonObject = Py::Object(new DrawViewDimExtentPy(this),true); + } + return Py::new_reference_to(PythonObject); +} diff --git a/src/Mod/TechDraw/App/DrawViewDimExtent.h b/src/Mod/TechDraw/App/DrawViewDimExtent.h new file mode 100644 index 0000000000..1fa967a400 --- /dev/null +++ b/src/Mod/TechDraw/App/DrawViewDimExtent.h @@ -0,0 +1,65 @@ +/*************************************************************************** + * Copyright (c) 2019 Wandererfan * + * * + * 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 _TechDraw_DrawViewDimExtent_h_ +#define _TechDraw_DrawViewDimExtent_h_ +#include + +# include +# include +# include + +#include "DrawViewDimension.h" + +namespace TechDraw { + +class TechDrawExport DrawViewDimExtent : public TechDraw::DrawViewDimension +{ + PROPERTY_HEADER(TechDraw::DrawViewDimExtent); + +public: + /// Constructor + DrawViewDimExtent(); + virtual ~DrawViewDimExtent(); + + App::PropertyLinkSubList Source; //DrawViewPart & SubElements(Edges) + //Cosmetic End points are stored in DVD::References2d + App::PropertyLinkSubList Source3d; //Part::Feature & SubElements TBI + App::PropertyInteger DirExtent; //Horizontal, Vertical, TBD + + virtual App::DocumentObjectExecReturn *execute(void); + virtual short mustExecute() const; + virtual void unsetupObject(); + + //return PyObject as DrawViewDimExtentPy + virtual PyObject *getPyObject(void); + + +protected: + void onChanged(const App::Property* prop); + std::vector getSubNames(void); + +private: +}; + +} //namespace TechDraw +#endif diff --git a/src/Mod/TechDraw/App/DrawViewDimExtentPy.xml b/src/Mod/TechDraw/App/DrawViewDimExtentPy.xml new file mode 100644 index 0000000000..804d2c75da --- /dev/null +++ b/src/Mod/TechDraw/App/DrawViewDimExtentPy.xml @@ -0,0 +1,23 @@ + + + + + + Feature for creating and manipulating Technical Drawing DimExtents + + + + tbd() - returns tbd. + + + + + diff --git a/src/Mod/TechDraw/App/DrawViewDimExtentPyImp.cpp b/src/Mod/TechDraw/App/DrawViewDimExtentPyImp.cpp new file mode 100644 index 0000000000..8bb9b68ec6 --- /dev/null +++ b/src/Mod/TechDraw/App/DrawViewDimExtentPyImp.cpp @@ -0,0 +1,62 @@ +/*************************************************************************** + * Copyright (c) WandererFan (wandererfan@gmail.com) 2019 * + * * + * 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_ +#endif + +#include +#include +#include + +#include "DrawViewDimExtent.h" + +// inclusion of the generated files (generated out of DrawViewDimExtentPy.xml) +#include +#include +#include + +using namespace TechDraw; + +// returns a string which represents the object e.g. when printed in python +std::string DrawViewDimExtentPy::representation(void) const +{ + return std::string(""); +} +PyObject* DrawViewDimExtentPy::tbd(PyObject* args) +{ + (void) args; + PyObject *pyText = nullptr; + return pyText; +} + + + +PyObject *DrawViewDimExtentPy::getCustomAttributes(const char* /*attr*/) const +{ + return 0; +} + +int DrawViewDimExtentPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/) +{ + return 0; +} diff --git a/src/Mod/TechDraw/App/DrawViewPart.cpp b/src/Mod/TechDraw/App/DrawViewPart.cpp index 9cf8c3a68a..e2699ffc43 100644 --- a/src/Mod/TechDraw/App/DrawViewPart.cpp +++ b/src/Mod/TechDraw/App/DrawViewPart.cpp @@ -68,6 +68,7 @@ #include #include #include + #include #endif @@ -119,7 +120,7 @@ using namespace std; PROPERTY_SOURCE(TechDraw::DrawViewPart, TechDraw::DrawView) -DrawViewPart::DrawViewPart(void) : +DrawViewPart::DrawViewPart(void) : geometryObject(0) { static const char *group = "Projection"; @@ -204,6 +205,7 @@ TopoDS_Shape DrawViewPart::getSourceShapeFused(void) const return result; } + App::DocumentObjectExecReturn *DrawViewPart::execute(void) { // Base::Console().Message("DVP::execute() - %s\n", Label.getValue()); @@ -239,10 +241,11 @@ App::DocumentObjectExecReturn *DrawViewPart::execute(void) gp_Pnt inputCenter; Base::Vector3d stdOrg(0.0,0.0,0.0); - + inputCenter = TechDraw::findCentroid(shape, getViewAxis(stdOrg,Direction.getValue())); + shapeCentroid = Base::Vector3d(inputCenter.X(),inputCenter.Y(),inputCenter.Z()); TopoDS_Shape mirroredShape; mirroredShape = TechDraw::mirrorShape(shape, @@ -646,7 +649,7 @@ std::vector DrawViewPart::getWireForFace(int idx) const TopoDS_Wire occwire = EdgeWalker::makeCleanWire(edges); result.push_back(occwire); } - + return result; } @@ -722,7 +725,7 @@ gp_Ax2 DrawViewPart::getViewAxis(const Base::Vector3d& pt, const bool flip) const { gp_Ax2 viewAxis = TechDraw::getViewAxis(pt,axis,flip); - + return viewAxis; } @@ -799,7 +802,7 @@ bool DrawViewPart::showSectionEdges(void) } //! remove features that are useless without this DVP -//! hatches, geomhatches, dimensions,... +//! hatches, geomhatches, dimensions,... void DrawViewPart::unsetupObject() { nowUnsetting = true; @@ -814,7 +817,7 @@ void DrawViewPart::unsetupObject() Base::Interpreter().runStringArg("App.getDocument(\"%s\").removeObject(\"%s\")", docName.c_str(), viewName.c_str()); } - + // Remove the View's GeomHatches from document std::vector gHatches = getGeomHatches(); std::vector::iterator it2 = gHatches.begin(); @@ -872,7 +875,7 @@ bool DrawViewPart::isIso(void) const //******** //* Cosmetics //******** -void DrawViewPart::clearCosmeticVertexes(void) +void DrawViewPart::clearCosmeticVertexes(void) { std::vector noVerts; CosmeticVertexes.setValues(noVerts); @@ -881,8 +884,8 @@ void DrawViewPart::clearCosmeticVertexes(void) //CosmeticVertex x,y are stored as unscaled, but mirrored values. //if you are creating a CV based on calculations of scaled geometry, you need to //unscale x,y before creation. -//if you are creating a CV based on calculations of mirrored geometry, you need to -//mirror again before creation. +//if you are creating a CV based on calculations of mirrored geometry, you need to +//mirror again before creation. //returns CosmeticVertex index! not geomVertexNumber! int DrawViewPart::addCosmeticVertex(Base::Vector3d pos) @@ -1000,18 +1003,44 @@ TechDraw::CosmeticVertex* DrawViewPart::getCosmeticVertexByGeom(int idx) const //add the cosmetic verts to geometry vertex list void DrawViewPart::addCosmeticVertexesToGeom(void) { - int i = 0; - const std::vector verts = CosmeticVertexes.getValues(); - int stop = (int) verts.size(); - for ( ; i < stop; i++) { - int idx = geometryObject->addCosmeticVertex((verts.at(i)->point()) * getScale(), i); - verts.at(i)->linkGeom = idx; +// Base::Console().Message("DVP::addCosmeticVertexesToGeom()\n"); + int iCV = 0; + const std::vector cVerts = CosmeticVertexes.getValues(); + const std::vector gVerts = getVertexGeometry(); + int stop = (int) cVerts.size(); + for ( ; iCV < stop; iCV++) { + int iGV = geometryObject->addCosmeticVertex(cVerts.at(iCV)->scaled(getScale()), iCV); + cVerts.at(iCV)->linkGeom = iGV; } } +int DrawViewPart::add1CVToGV(int iCV) +{ +// Base::Console().Message("DVP::add1CVToGV(%d)\n", iCV); + TechDraw::CosmeticVertex* cv = getCosmeticVertexByIndex(iCV); + int iGV = geometryObject->addCosmeticVertex(cv->scaled(getScale()), iCV); + cv->linkGeom = iGV; + return iGV; +} + +//given a CosmeticVertex's index, return the corresponding geometry vertex's index +int DrawViewPart::convertCosmeticVertexIndex(int iCV) +{ +// Base::Console().Message("DVP::convertCosmeticVertexIndex(%d)\n",iCV); + int result = -1; + if (geometryObject != nullptr) { + std::vector cVerts = CosmeticVertexes.getValues(); + TechDraw::CosmeticVertex* cv = cVerts.at(iCV); + int temp = cv->linkGeom; + result = temp; + //could double check with tag comparison + } + return result; +} + //CosmeticEdges ------------------------------------------------------------------- -void DrawViewPart::clearCosmeticEdges(void) +void DrawViewPart::clearCosmeticEdges(void) { std::vector noEdges; std::vector edges = CosmeticEdges.getValues(); @@ -1152,17 +1181,17 @@ void DrawViewPart::addCosmeticEdgesToGeom(void) int stop = (int) edges.size(); for ( ; i < stop; i++) { TechDraw::BaseGeom* scaledGeom = edges.at(i)->scaledGeometry(getScale()); - if (scaledGeom == nullptr) { + if (scaledGeom == nullptr) { Base::Console().Error("DVP::addCosmeticEdgesToGeom - scaledGeometry is null\n"); continue; } -// int idx = +// int idx = (void) geometryObject->addCosmeticEdge(scaledGeom, 1, i); } } // CenterLines ----------------------------------------------------------------- -void DrawViewPart::clearCenterLines(void) +void DrawViewPart::clearCenterLines(void) { std::vector noLines; std::vector lines = CenterLines.getValues(); @@ -1257,18 +1286,18 @@ void DrawViewPart::addCenterLinesToGeom(void) int stop = (int) lines.size(); for ( ; i < stop; i++) { TechDraw::BaseGeom* scaledGeom = lines.at(i)->scaledGeometry(this); - if (scaledGeom == nullptr) { + if (scaledGeom == nullptr) { Base::Console().Error("DVP::addCenterLinesToGeom - scaledGeometry is null\n"); continue; } -// int idx = +// int idx = (void) geometryObject->addCenterLine(scaledGeom, 2, i); } } // GeomFormats ----------------------------------------------------------------- -void DrawViewPart::clearGeomFormats(void) +void DrawViewPart::clearGeomFormats(void) { std::vector noFormats; std::vector fmts = GeomFormats.getValues(); @@ -1323,6 +1352,22 @@ TechDraw::GeomFormat* DrawViewPart::getGeomFormatByGeom(int idx) const return result; } +//------------------------------------------------------------------------------ + +void DrawViewPart::dumpVerts(std::string text) +{ + if (geometryObject == nullptr) { + Base::Console().Message("no verts to dump yet\n"); + return; + } + std::vector gVerts = getVertexGeometry(); + Base::Console().Message("%s - dumping %d vertGeoms\n", + text.c_str(), gVerts.size()); + for (auto& gv: gVerts) { + gv->dump(); + } +} + void DrawViewPart::onDocumentRestored() { // requestPaint(); diff --git a/src/Mod/TechDraw/App/DrawViewPart.h b/src/Mod/TechDraw/App/DrawViewPart.h index f840d84e95..389f420bfc 100644 --- a/src/Mod/TechDraw/App/DrawViewPart.h +++ b/src/Mod/TechDraw/App/DrawViewPart.h @@ -179,6 +179,10 @@ public: TechDraw::CosmeticVertex* getCosmeticVertexByGeom(int idx) const; void clearCosmeticVertexes(void); void addCosmeticVertexesToGeom(void); + void add1CosmeticVertexToGeom(int iCV); + int convertCosmeticVertexIndex(int idx); + int add1CVToGV(int iCV); + virtual int addCosmeticEdge(Base::Vector3d start, Base::Vector3d end); virtual int addCosmeticEdge(TopoDS_Edge e); @@ -209,6 +213,8 @@ public: TechDraw::GeomFormat* getGeomFormatByGeom(int idx) const; void clearGeomFormats(void); + void dumpVerts(std::string text); + protected: TechDraw::GeometryObject *geometryObject; Base::BoundBox3d bbox; diff --git a/src/Mod/TechDraw/App/Geometry.cpp b/src/Mod/TechDraw/App/Geometry.cpp index bf5cde8abf..236cc8ff7f 100644 --- a/src/Mod/TechDraw/App/Geometry.cpp +++ b/src/Mod/TechDraw/App/Geometry.cpp @@ -353,6 +353,7 @@ std::string BaseGeom::dump() std::stringstream ss; ss << "BaseGeom: s:(" << start.x << "," << start.y << ") e:(" << end.x << "," << end.y << ") "; ss << "type: " << geomType << " class: " << classOfEdge << " viz: " << visible << " rev: " << reversed; + ss << "cosmetic: " << cosmetic << " source: " << source() << " iSource: " << sourceIndex(); return ss.str(); } @@ -1336,6 +1337,13 @@ Vertex::Vertex(double x, double y) cosmeticLink = -1; } +Vertex::Vertex(Base::Vector3d v) : Vertex(v.x,v.y) +{ +// Base::Console().Message("V::V(%s)\n", +// DrawUtil::formatVector(v).c_str()); +} + + bool Vertex::isEqual(Vertex* v, double tol) { bool result = false; @@ -1389,6 +1397,12 @@ void Vertex::Restore(Base::XMLReader &reader) occVertex = mkVert.Vertex(); } +void Vertex::dump() +{ + Base::Console().Message("TD::Vertex point: %s vis: %d cosmetic: %d cosLink: %d\n", + DrawUtil::formatVector(pnt).c_str(), visible, cosmetic, cosmeticLink); +} + /*static*/ BaseGeomPtrVector GeometryUtils::chainGeoms(BaseGeomPtrVector geoms) diff --git a/src/Mod/TechDraw/App/Geometry.h b/src/Mod/TechDraw/App/Geometry.h index eeb3fa7589..db7ea02590 100644 --- a/src/Mod/TechDraw/App/Geometry.h +++ b/src/Mod/TechDraw/App/Geometry.h @@ -23,6 +23,8 @@ #ifndef TECHDRAW_GEOMETRY_H #define TECHDRAW_GEOMETRY_H +#include + #include #include #include @@ -281,11 +283,13 @@ class TechDrawExport Vertex Vertex(); Vertex(const Vertex* v); Vertex(double x, double y); - Vertex(Base::Vector3d v) : Vertex(v.x,v.y) {} + Vertex(Base::Vector3d v); virtual ~Vertex() {} virtual void Save(Base::Writer &/*writer*/) const; virtual void Restore(Base::XMLReader &/*reader*/); + virtual std::string getTagAsString() const { return std::string(); } + virtual void dump(); Base::Vector3d pnt; ExtractionType extractType; //obs? @@ -298,6 +302,8 @@ class TechDrawExport Vertex void point(Base::Vector3d v){ pnt = Base::Vector3d(v.x, v.y); } bool cosmetic; int cosmeticLink; + boost::uuids::uuid cosmeticTag; + double x() {return pnt.x;} double y() {return pnt.y;} diff --git a/src/Mod/TechDraw/App/GeometryObject.cpp b/src/Mod/TechDraw/App/GeometryObject.cpp index 4e8a0272af..2d3ca40375 100644 --- a/src/Mod/TechDraw/App/GeometryObject.cpp +++ b/src/Mod/TechDraw/App/GeometryObject.cpp @@ -474,11 +474,13 @@ void GeometryObject::addGeomFromCompound(TopoDS_Shape edgeCompound, edgeClass ca } //end TopExp } +//adds a new GeomVert to list for cv[link] int GeometryObject::addCosmeticVertex(Base::Vector3d pos, int link) { TechDraw::Vertex* v = new TechDraw::Vertex(pos.x, pos.y); v->cosmetic = true; v->cosmeticLink = link; + v->visible = true; int idx = vertexGeom.size(); vertexGeom.push_back(v); return idx; @@ -573,6 +575,7 @@ bool GeometryObject::isWithinArc(double theta, double first, } } +//note bbx is scaled Base::BoundBox3d GeometryObject::calcBoundingBox() const { // Base::Console().Message("GO::calcBoundingBox() - edges: %d\n", edgeGeom.size()); diff --git a/src/Mod/TechDraw/Gui/CommandCreateDims.cpp b/src/Mod/TechDraw/Gui/CommandCreateDims.cpp index f701539b3b..636dde3ad5 100644 --- a/src/Mod/TechDraw/Gui/CommandCreateDims.cpp +++ b/src/Mod/TechDraw/Gui/CommandCreateDims.cpp @@ -53,6 +53,7 @@ # include # include # include +# include # include # include # include @@ -66,6 +67,7 @@ #include "TaskLinkDim.h" using namespace TechDrawGui; +using namespace TechDraw; using namespace std; @@ -99,6 +101,9 @@ bool _isValidVertexToEdge(Gui::Command* cmd); char* _edgeTypeToText(int e); //bool _checkActive(Gui::Command* cmd, Base::Type classType, bool needSubs); +void execHExtent(Gui::Command* cmd); +void execVExtent(Gui::Command* cmd); + //NOTE: this is not shown in toolbar and doesn't always work right in the menu. // should be removed. @@ -1070,6 +1075,270 @@ bool CmdTechDrawLinkDimension::isActive(void) return (havePage && haveView && !taskInProgress); } +//=========================================================================== +// ExtentGroup +//=========================================================================== + +DEF_STD_CMD_ACL(CmdTechDrawExtentGrp) + +CmdTechDrawExtentGrp::CmdTechDrawExtentGrp() + : Command("TechDraw_ExtentGrp") +{ + sAppModule = "TechDraw"; + sGroup = QT_TR_NOOP("TechDraw"); + sMenuText = QT_TR_NOOP("Insert Extent Dimension"); + sToolTipText = QT_TR_NOOP("Insert Extent Dimension"); + sWhatsThis = "TechDraw_ExtentGrp"; + sStatusTip = sToolTipText; +// eType = ForEdit; +} + +void CmdTechDrawExtentGrp::activated(int iMsg) +{ +// Base::Console().Message("CMD::ExtentGrp - activated(%d)\n", iMsg); + Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog(); + if (dlg != nullptr) { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Task In Progress"), + QObject::tr("Close active task dialog and try again.")); + return; + } + + Gui::ActionGroup* pcAction = qobject_cast(_pcAction); + pcAction->setIcon(pcAction->actions().at(iMsg)->icon()); + switch(iMsg) { + case 0: + execHExtent(this); + break; + case 1: + execVExtent(this); + break; + default: + Base::Console().Message("CMD::ExtGrp - invalid iMsg: %d\n",iMsg); + }; +} + +Gui::Action * CmdTechDrawExtentGrp::createAction(void) +{ + Gui::ActionGroup* pcAction = new Gui::ActionGroup(this, Gui::getMainWindow()); + pcAction->setDropDownMenu(true); + applyCommandData(this->className(), pcAction); + + QAction* p1 = pcAction->addAction(QString()); + p1->setIcon(Gui::BitmapFactory().iconFromTheme("TechDraw_Dimension_HExtent")); + p1->setObjectName(QString::fromLatin1("TechDraw_HorizontalExtent")); + p1->setWhatsThis(QString::fromLatin1("TechDraw_HorizontalExtent")); + QAction* p2 = pcAction->addAction(QString()); + p2->setIcon(Gui::BitmapFactory().iconFromTheme("TechDraw_Dimension_VExtent")); + p2->setObjectName(QString::fromLatin1("TechDraw_VerticalExtent")); + p2->setWhatsThis(QString::fromLatin1("TechDraw_VerticalExtent")); + + _pcAction = pcAction; + languageChange(); + + pcAction->setIcon(p1->icon()); + int defaultId = 0; + pcAction->setProperty("defaultAction", QVariant(defaultId)); + + return pcAction; +} + +void CmdTechDrawExtentGrp::languageChange() +{ + Command::languageChange(); + + if (!_pcAction) + return; + Gui::ActionGroup* pcAction = qobject_cast(_pcAction); + QList a = pcAction->actions(); + + QAction* arc1 = a[0]; + arc1->setText(QApplication::translate("CmdTechDrawExtentGrp","Horizontal Extent")); + arc1->setToolTip(QApplication::translate("TechDraw_HorizontalExtent","Insert a Horizontal Extent dimension")); + arc1->setStatusTip(arc1->toolTip()); + QAction* arc2 = a[1]; + arc2->setText(QApplication::translate("CmdTechDrawExtentGrp","Vertical Extent")); + arc2->setToolTip(QApplication::translate("TechDraw_VerticalExtent","Insert a Vertical Extent dimension")); + arc2->setStatusTip(arc2->toolTip()); +} + +bool CmdTechDrawExtentGrp::isActive(void) +{ + bool havePage = DrawGuiUtil::needPage(this); + bool haveView = DrawGuiUtil::needView(this, false); + return (havePage && haveView); +} + +//=========================================================================== +// TechDraw_HorizontalExtent +//=========================================================================== + +DEF_STD_CMD_A(CmdTechDrawHorizontalExtent) + +CmdTechDrawHorizontalExtent::CmdTechDrawHorizontalExtent() + : Command("TechDraw_HorizontalExtent") +{ + sAppModule = "TechDraw"; + sGroup = QT_TR_NOOP("TechDraw"); + sMenuText = QT_TR_NOOP("Add a Horizontal Extent dimension"); + sToolTipText = QT_TR_NOOP("Add a Horizontal Extent dimension"); + sWhatsThis = "TechDraw_HorizontalExtent"; + sStatusTip = sToolTipText; + sPixmap = "TechDraw_Dimension_HExtent"; +} + +void CmdTechDrawHorizontalExtent::activated(int iMsg) +{ + Q_UNUSED(iMsg); + + Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog(); + if (dlg != nullptr) { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Task In Progress"), + QObject::tr("Close active task dialog and try again.")); + return; + } + + execHExtent(this); +} + +bool CmdTechDrawHorizontalExtent::isActive(void) +{ + bool havePage = DrawGuiUtil::needPage(this); + bool haveView = DrawGuiUtil::needView(this, false); + return (havePage && haveView); +} + +void execHExtent(Gui::Command* cmd) +{ + TechDraw::DrawPage* page = DrawGuiUtil::findPage(cmd); + if (!page) { + return; + } + + std::vector selection = cmd->getSelection().getSelectionEx(); + TechDraw::DrawViewPart* baseFeat = nullptr; + if (!selection.empty()) { + baseFeat = dynamic_cast(selection[0].getObject()); + if( baseFeat == nullptr ) { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Selection Error"), + QObject::tr("No base View in Selection.")); + return; + } + } else { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Selection Error"), + QObject::tr("Please select a View [and Edges].")); + return; + } + + std::vector SubNames; + + std::vector::iterator itSel = selection.begin(); + for (; itSel != selection.end(); itSel++) { + if ((*itSel).getObject()->isDerivedFrom(TechDraw::DrawViewPart::getClassTypeId())) { + // baseFeat = static_cast ((*itSel).getObject()); + SubNames = (*itSel).getSubNames(); + if (SubNames.empty() || SubNames[0].empty()) { + SubNames.clear(); + } + } + } + + std::vector edgeNames; + for (auto& s: SubNames) { + std::string geomType = DrawUtil::getGeomTypeFromName(s); + if (geomType == "Edge") { + edgeNames.push_back(s); + } + } + + DrawDimHelper::makeExtentDim(baseFeat, + edgeNames, + 0); +} + +//=========================================================================== +// TechDraw_VerticalExtent +//=========================================================================== + +DEF_STD_CMD_A(CmdTechDrawVerticalExtent) + +CmdTechDrawVerticalExtent::CmdTechDrawVerticalExtent() + : Command("TechDraw_VerticalExtent") +{ + sAppModule = "TechDraw"; + sGroup = QT_TR_NOOP("TechDraw"); + sMenuText = QT_TR_NOOP("Add a Vertical Extent dimension"); + sToolTipText = QT_TR_NOOP("Add a Vertical Extent dimension"); + sWhatsThis = "TechDraw_VerticalExtent"; + sStatusTip = sToolTipText; + sPixmap = "TechDraw_Dimension_VExtent"; +} + +void CmdTechDrawVerticalExtent::activated(int iMsg) +{ + Q_UNUSED(iMsg); + + Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog(); + if (dlg != nullptr) { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Task In Progress"), + QObject::tr("Close active task dialog and try again.")); + return; + } + + execVExtent(this); +} + +bool CmdTechDrawVerticalExtent::isActive(void) +{ + bool havePage = DrawGuiUtil::needPage(this); + bool haveView = DrawGuiUtil::needView(this, false); + return (havePage && haveView); +} + +void execVExtent(Gui::Command* cmd) +{ + TechDraw::DrawPage* page = DrawGuiUtil::findPage(cmd); + if (!page) { + return; + } + + std::vector selection = cmd->getSelection().getSelectionEx(); + TechDraw::DrawViewPart* baseFeat = nullptr; + if (!selection.empty()) { + baseFeat = dynamic_cast(selection[0].getObject()); + if( baseFeat == nullptr ) { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Selection Error"), + QObject::tr("No base View in Selection.")); + return; + } + } else { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Selection Error"), + QObject::tr("Please select a View [and Edges].")); + return; + } + + std::vector SubNames; + + std::vector::iterator itSel = selection.begin(); + for (; itSel != selection.end(); itSel++) { + if ((*itSel).getObject()->isDerivedFrom(TechDraw::DrawViewPart::getClassTypeId())) { + baseFeat = static_cast ((*itSel).getObject()); + SubNames = (*itSel).getSubNames(); + } + } + std::vector edgeNames; + for (auto& s: SubNames) { + std::string geomType = DrawUtil::getGeomTypeFromName(s); + if (geomType == "Edge") { + edgeNames.push_back(s); + } + } + + DrawDimHelper::makeExtentDim(baseFeat, + edgeNames, + 1); +} + +//------------------------------------------------------------------------------ void CreateTechDrawCommandsDims(void) { Gui::CommandManager &rcCmdMgr = Gui::Application::Instance->commandManager(); @@ -1082,6 +1351,9 @@ void CreateTechDrawCommandsDims(void) rcCmdMgr.addCommand(new CmdTechDrawNewDistanceYDimension()); rcCmdMgr.addCommand(new CmdTechDrawNewAngleDimension()); rcCmdMgr.addCommand(new CmdTechDrawNewAngle3PtDimension()); + rcCmdMgr.addCommand(new CmdTechDrawExtentGrp()); + rcCmdMgr.addCommand(new CmdTechDrawVerticalExtent()); + rcCmdMgr.addCommand(new CmdTechDrawHorizontalExtent()); rcCmdMgr.addCommand(new CmdTechDrawLinkDimension()); } diff --git a/src/Mod/TechDraw/Gui/Resources/TechDraw.qrc b/src/Mod/TechDraw/Gui/Resources/TechDraw.qrc index a1975c8939..a6cb51bddf 100644 --- a/src/Mod/TechDraw/Gui/Resources/TechDraw.qrc +++ b/src/Mod/TechDraw/Gui/Resources/TechDraw.qrc @@ -33,6 +33,8 @@ icons/TechDraw_Balloon.svg icons/TechDraw_Dimension_Vertical.svg icons/TechDraw_Dimension_Link.svg + icons/TechDraw_Dimension_HExtent.svg + icons/TechDraw_Dimension_VExtent.svg icons/preferences-techdraw.svg icons/arrowdot.svg icons/arrowopendot.svg diff --git a/src/Mod/TechDraw/Gui/Resources/icons/TechDraw_Dimension_HExtent.svg b/src/Mod/TechDraw/Gui/Resources/icons/TechDraw_Dimension_HExtent.svg new file mode 100644 index 0000000000..586971ef96 --- /dev/null +++ b/src/Mod/TechDraw/Gui/Resources/icons/TechDraw_Dimension_HExtent.svg @@ -0,0 +1,909 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + [agryson] Alexander Gryson + + + http://agryson.net + + techdraw-view + 2016-01-14 + http://www.freecadweb.org/wiki/index.php?title=Artwork + + + FreeCAD + + + FreeCAD/src/Mod/TechDraw/Gui/Resources/icons/actions/techdraw-view.svg + + + FreeCAD LGPL2+ + + + + + [agryson] Alexander Gryson + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Mod/TechDraw/Gui/Resources/icons/TechDraw_Dimension_VExtent.svg b/src/Mod/TechDraw/Gui/Resources/icons/TechDraw_Dimension_VExtent.svg new file mode 100644 index 0000000000..20bff07a7f --- /dev/null +++ b/src/Mod/TechDraw/Gui/Resources/icons/TechDraw_Dimension_VExtent.svg @@ -0,0 +1,909 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + [agryson] Alexander Gryson + + + http://agryson.net + + techdraw-view + 2016-01-14 + http://www.freecadweb.org/wiki/index.php?title=Artwork + + + FreeCAD + + + FreeCAD/src/Mod/TechDraw/Gui/Resources/icons/actions/techdraw-view.svg + + + FreeCAD LGPL2+ + + + + + [agryson] Alexander Gryson + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Mod/TechDraw/Gui/Workbench.cpp b/src/Mod/TechDraw/Gui/Workbench.cpp index e3f2813d53..e4587eb9c1 100644 --- a/src/Mod/TechDraw/Gui/Workbench.cpp +++ b/src/Mod/TechDraw/Gui/Workbench.cpp @@ -76,7 +76,8 @@ Gui::MenuItem* Workbench::setupMenuBar() const *draw << "TechDraw_NewRadiusDimension"; *draw << "TechDraw_NewDiameterDimension"; *draw << "TechDraw_NewAngleDimension"; - *draw << "TechDraw_NewAngle3PtDimension"; + *draw << "TechDraw_HorizontalExtent"; + *draw << "TechDraw_VerticalExtent"; *draw << "TechDraw_LinkDimension"; *draw << "TechDraw_NewBalloon"; *draw << "Separator"; @@ -141,6 +142,9 @@ Gui::ToolBarItem* Workbench::setupToolBars() const *dims << "TechDraw_NewDiameterDimension"; *dims << "TechDraw_NewAngleDimension"; *dims << "TechDraw_NewAngle3PtDimension"; + *dims << "TechDraw_ExtentGrp"; +// *dims << "TechDraw_HorizontalExtent"; +// *dims << "TechDraw_VerticalExtent"; *dims << "TechDraw_LinkDimension"; *dims << "TechDraw_NewBalloon"; // *dims << "TechDraw_NewDimension" @@ -210,6 +214,9 @@ Gui::ToolBarItem* Workbench::setupCommandBars() const *dims << "TechDraw_NewDiameterDimension"; *dims << "TechDraw_NewAngleDimension"; *dims << "TechDraw_NewAngle3PtDimension"; + *dims << "TechDraw_ExtentGrp"; +// *dims << "TechDraw_HorizontalExtent"; +// *dims << "TechDraw_VerticalExtent"; *dims << "TechDraw_LinkDimension"; *dims << "TechDraw_NewBalloon"; // *dims << "TechDraw_NewDimension";