diff --git a/src/Mod/Measure/App/Measurement.cpp b/src/Mod/Measure/App/Measurement.cpp index 57a4a9838..061dc2931 100644 --- a/src/Mod/Measure/App/Measurement.cpp +++ b/src/Mod/Measure/App/Measurement.cpp @@ -85,6 +85,12 @@ bool Measurement::has3DReferences() return (References3D.getSize() > 0); } +//add a 3D reference (obj+sub) to end of list +int Measurement::addReference3D(App::DocumentObject *obj, const std::string subName) +{ + return addReference3D(obj,subName.c_str()); +} + ///add a 3D reference (obj+sub) to end of list int Measurement::addReference3D(App::DocumentObject *obj, const char* subName) { diff --git a/src/Mod/Measure/App/Measurement.h b/src/Mod/Measure/App/Measurement.h index 29f7f20c1..9da4e8efb 100644 --- a/src/Mod/Measure/App/Measurement.h +++ b/src/Mod/Measure/App/Measurement.h @@ -58,6 +58,7 @@ public: bool has3DReferences(); /// Add a reference + int addReference3D(App::DocumentObject* obj, const std::string subName); int addReference3D(App::DocumentObject* obj, const char *subName); MeasureType getType(); diff --git a/src/Mod/TechDraw/App/AppTechDraw.cpp b/src/Mod/TechDraw/App/AppTechDraw.cpp index eb455d8f3..7bd8d5367 100644 --- a/src/Mod/TechDraw/App/AppTechDraw.cpp +++ b/src/Mod/TechDraw/App/AppTechDraw.cpp @@ -34,6 +34,8 @@ #include "DrawViewDraft.h" #include "DrawViewArch.h" #include "DrawViewSpreadsheet.h" +#include "DrawViewMulti.h" +#include "DrawViewImage.h" namespace TechDraw { extern PyObject* initModule(); @@ -68,6 +70,7 @@ PyMODINIT_FUNC initTechDraw() TechDraw::DrawViewSpreadsheet ::init(); TechDraw::DrawViewSection ::init(); + TechDraw::DrawViewMulti ::init(); TechDraw::DrawViewDimension ::init(); TechDraw::DrawProjGroup ::init(); TechDraw::DrawProjGroupItem ::init(); @@ -79,10 +82,12 @@ PyMODINIT_FUNC initTechDraw() TechDraw::DrawHatch ::init(); TechDraw::DrawViewDraft ::init(); TechDraw::DrawViewArch ::init(); + TechDraw::DrawViewImage ::init(); // Python Types TechDraw::DrawViewPython ::init(); TechDraw::DrawViewPartPython ::init(); + TechDraw::DrawViewMultiPython ::init(); TechDraw::DrawTemplatePython ::init(); TechDraw::DrawViewSymbolPython::init(); } diff --git a/src/Mod/TechDraw/App/AppTechDrawPy.cpp b/src/Mod/TechDraw/App/AppTechDrawPy.cpp index cbe054575..cf06d84e9 100644 --- a/src/Mod/TechDraw/App/AppTechDrawPy.cpp +++ b/src/Mod/TechDraw/App/AppTechDrawPy.cpp @@ -38,6 +38,8 @@ #include #include #include +#include +#include #include #include @@ -46,8 +48,10 @@ #include +#include "DrawProjectSplit.h" #include "EdgeWalker.h" + namespace TechDraw { //module level static C++ functions go here } @@ -70,6 +74,9 @@ public: add_varargs_method("findOuterWire",&Module::findOuterWire, "wire = findOuterWire(edgeList) -- Planar graph traversal finds OuterWire in edge pile." ); + add_varargs_method("findShapeOutline",&Module::findShapeOutline, + "wire = findShapeOutline(shape,scale,direction) -- Project shape in direction and find outer wire of result." + ); initialize("This is a module for making drawings"); // register with Python } virtual ~Module() {} @@ -219,6 +226,62 @@ private: } return Py::asObject(outerWire); } + + Py::Object findShapeOutline(const Py::Tuple& args) + { + PyObject *pcObjShape; + double scale; + PyObject *pcObjDir; + if (!PyArg_ParseTuple(args.ptr(), "OdO", &pcObjShape, + &scale, + &pcObjDir)) { + throw Py::Exception(); + } + + TopoShapePy* pShape = static_cast(pcObjShape); + if (!pShape) { + Base::Console().Message("TRACE - AATDP::findShapeOutline - input shape is null\n"); + return Py::None(); + } + + const TopoDS_Shape& shape = pShape->getTopoShapePtr()->getShape(); + Base::Vector3d dir = static_cast(pcObjDir)->value(); + std::vector edgeList; + try { + edgeList = DrawProjectSplit::getEdgesForWalker(shape,scale,dir); + } + catch (Standard_Failure) { + Handle_Standard_Failure e = Standard_Failure::Caught(); + throw Py::Exception(Part::PartExceptionOCCError, e->GetMessageString()); + } + + if (edgeList.empty()) { + Base::Console().Log("LOG - ATDP::findShapeOutline: input is empty\n"); + return Py::None(); + } + + PyObject* outerWire = nullptr; + bool success = false; + try { + EdgeWalker ew; + ew.loadEdges(edgeList); + success = ew.perform(); + if (success) { + std::vector rw = ew.getResultNoDups(); + std::vector sortedWires = ew.sortStrip(rw,true); + outerWire = new TopoShapeWirePy(new TopoShape(*sortedWires.begin())); + } else { + Base::Console().Warning("ATDP::findShapeOutline: input is not planar graph. Wire detection not done\n"); + } + } + catch (Base::Exception &e) { + throw Py::Exception(Base::BaseExceptionFreeCADError, e.what()); + } + if (!success) { + return Py::None(); + } + return Py::asObject(outerWire); + } }; PyObject* initModule() diff --git a/src/Mod/TechDraw/App/CMakeLists.txt b/src/Mod/TechDraw/App/CMakeLists.txt index 92a75ed4d..65b351f24 100644 --- a/src/Mod/TechDraw/App/CMakeLists.txt +++ b/src/Mod/TechDraw/App/CMakeLists.txt @@ -79,7 +79,10 @@ SET(Draw_SRCS DrawViewDraft.h DrawViewArch.cpp DrawViewArch.h -) + DrawViewMulti.cpp + DrawViewMulti.h + DrawViewImage.cpp + DrawViewImage.h) SET(TechDraw_SRCS AppTechDraw.cpp @@ -90,6 +93,8 @@ SET(TechDraw_SRCS PreCompiled.h EdgeWalker.cpp EdgeWalker.h + DrawProjectSplit.cpp + DrawProjectSplit.h ) SET(Geometry_SRCS diff --git a/src/Mod/TechDraw/App/DrawProjectSplit.cpp b/src/Mod/TechDraw/App/DrawProjectSplit.cpp new file mode 100644 index 000000000..c5b54e90a --- /dev/null +++ b/src/Mod/TechDraw/App/DrawProjectSplit.cpp @@ -0,0 +1,428 @@ +/*************************************************************************** + * Copyright (c) WandererFan (wandererfan@gmail.com) 2016 * + * * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "DrawUtil.h" +#include "Geometry.h" +#include "GeometryObject.h" +#include "DrawProjectSplit.h" +#include "DrawHatch.h" +#include "EdgeWalker.h" + + +//#include // generated from DrawProjectSplitPy.xml + +using namespace TechDraw; +using namespace std; + + +//=========================================================================== +// DrawProjectSplit +//=========================================================================== + +DrawProjectSplit::DrawProjectSplit() +{ +} + +DrawProjectSplit::~DrawProjectSplit() +{ +} + +std::vector DrawProjectSplit::getEdgesForWalker(TopoDS_Shape shape, double scale, Base::Vector3d direction) +{ + std::vector result; + if (shape.IsNull()) { + return result; + } + + BRepBuilderAPI_Copy BuilderCopy(shape); + TopoDS_Shape copyShape = BuilderCopy.Shape(); + + gp_Pnt inputCenter(0,0,0); + TopoDS_Shape scaledShape; + scaledShape = TechDrawGeometry::scaleShape(copyShape, + scale); + TechDrawGeometry::GeometryObject* go = buildGeometryObject(scaledShape,inputCenter,direction); + result = getEdges(go); + + delete go; + return result; +} + + +TechDrawGeometry::GeometryObject* DrawProjectSplit::buildGeometryObject( + TopoDS_Shape shape, + gp_Pnt& inputCenter, + Base::Vector3d direction) +{ + TechDrawGeometry::GeometryObject* geometryObject = new TechDrawGeometry::GeometryObject("DrawProjectSplit"); + + geometryObject->projectShape(shape, + inputCenter, + direction); + geometryObject->extractGeometry(TechDrawGeometry::ecHARD, //always show the hard&outline visible lines + true); + geometryObject->extractGeometry(TechDrawGeometry::ecOUTLINE, + true); + return geometryObject; +} + +//! get the projected edges with all their new intersections. +std::vector DrawProjectSplit::getEdges(TechDrawGeometry::GeometryObject* geometryObject) +{ + const std::vector& goEdges = geometryObject->getVisibleFaceEdges(true,true); + std::vector::const_iterator itEdge = goEdges.begin(); + std::vector origEdges; + for (;itEdge != goEdges.end(); itEdge++) { + origEdges.push_back((*itEdge)->occEdge); + } + + std::vector faceEdges; + std::vector nonZero; + for (auto& e:origEdges) { //drop any zero edges (shouldn't be any by now!!!) + if (!DrawUtil::isZeroEdge(e)) { + nonZero.push_back(e); + } else { + Base::Console().Message("INFO - DPS::extractFaces found ZeroEdge!\n"); + } + } + faceEdges = nonZero; + origEdges = nonZero; + + //HLR algo does not provide all edge intersections for edge endpoints. + //need to split long edges touched by Vertex of another edge + std::vector splits; + std::vector::iterator itOuter = origEdges.begin(); + int iOuter = 0; + for (; itOuter != origEdges.end(); itOuter++, iOuter++) { + TopoDS_Vertex v1 = TopExp::FirstVertex((*itOuter)); + TopoDS_Vertex v2 = TopExp::LastVertex((*itOuter)); + Bnd_Box sOuter; + BRepBndLib::Add(*itOuter, sOuter); + sOuter.SetGap(0.1); + if (sOuter.IsVoid()) { + Base::Console().Message("DPS::Extract Faces - outer Bnd_Box is void\n"); + continue; + } + if (DrawUtil::isZeroEdge(*itOuter)) { + Base::Console().Message("DPS::extractFaces - outerEdge: %d is ZeroEdge\n",iOuter); //this is not finding ZeroEdges + continue; //skip zero length edges. shouldn't happen ;) + } + int iInner = 0; + std::vector::iterator itInner = faceEdges.begin(); + for (; itInner != faceEdges.end(); itInner++,iInner++) { + if (iInner == iOuter) { + continue; + } + if (DrawUtil::isZeroEdge((*itInner))) { + continue; //skip zero length edges. shouldn't happen ;) + } + + Bnd_Box sInner; + BRepBndLib::Add(*itInner, sInner); + sInner.SetGap(0.1); + if (sInner.IsVoid()) { + Base::Console().Log("INFO - DPS::Extract Faces - inner Bnd_Box is void\n"); + continue; + } + if (sOuter.IsOut(sInner)) { //bboxes of edges don't intersect, don't bother + continue; + } + + double param = -1; + if (isOnEdge((*itInner),v1,param,false)) { + gp_Pnt pnt1 = BRep_Tool::Pnt(v1); + splitPoint s1; + s1.i = iInner; + s1.v = Base::Vector3d(pnt1.X(),pnt1.Y(),pnt1.Z()); + s1.param = param; + splits.push_back(s1); + } + if (isOnEdge((*itInner),v2,param,false)) { + gp_Pnt pnt2 = BRep_Tool::Pnt(v2); + splitPoint s2; + s2.i = iInner; + s2.v = Base::Vector3d(pnt2.X(),pnt2.Y(),pnt2.Z()); + s2.param = param; + splits.push_back(s2); + } + } //inner loop + } //outer loop + + std::vector sorted = sortSplits(splits,true); + auto last = std::unique(sorted.begin(), sorted.end(), DrawProjectSplit::splitEqual); //duplicates to back + sorted.erase(last, sorted.end()); //remove dupls + std::vector newEdges = splitEdges(faceEdges,sorted); + + if (newEdges.empty()) { + Base::Console().Log("LOG - DPS::extractFaces - no newEdges\n"); + } + return newEdges; +} + + +double DrawProjectSplit::simpleMinDist(TopoDS_Shape s1, TopoDS_Shape s2) +{ + Standard_Real minDist = -1; + + BRepExtrema_DistShapeShape extss(s1, s2); + if (!extss.IsDone()) { + Base::Console().Message("FE - BRepExtrema_DistShapeShape failed"); + return -1; + } + int count = extss.NbSolution(); + if (count != 0) { + minDist = extss.Value(); + } else { + minDist = -1; + } + return minDist; +} + + +//this routine is the big time consumer. gets called many times (and is slow?)) +//note param gets modified here +bool DrawProjectSplit::isOnEdge(TopoDS_Edge e, TopoDS_Vertex v, double& param, bool allowEnds) +{ + bool result = false; + bool outOfBox = false; + param = -2; + + //eliminate obvious cases + Bnd_Box sBox; + BRepBndLib::Add(e, sBox); + sBox.SetGap(0.1); + if (sBox.IsVoid()) { + Base::Console().Message("DPS::isOnEdge - Bnd_Box is void\n"); + } else { + gp_Pnt pt = BRep_Tool::Pnt(v); + if (sBox.IsOut(pt)) { + outOfBox = true; + } + } + if (!outOfBox) { + double dist = simpleMinDist(v,e); + if (dist < 0.0) { + Base::Console().Error("DPS::isOnEdge - simpleMinDist failed: %.3f\n",dist); + result = false; + } else if (dist < Precision::Confusion()) { + const gp_Pnt pt = BRep_Tool::Pnt(v); //have to duplicate method 3 to get param + BRepAdaptor_Curve adapt(e); + const Handle_Geom_Curve c = adapt.Curve().Curve(); + double maxDist = 0.000001; //magic number. less than this gives false positives. + //bool found = + (void) GeomLib_Tool::Parameter(c,pt,maxDist,param); //already know point it on curve + result = true; + } + if (result) { + TopoDS_Vertex v1 = TopExp::FirstVertex(e); + TopoDS_Vertex v2 = TopExp::LastVertex(e); + if (DrawUtil::isSamePoint(v,v1) || DrawUtil::isSamePoint(v,v2)) { + if (!allowEnds) { + result = false; + } + } + } + } //!outofbox + return result; +} + + +std::vector DrawProjectSplit::splitEdges(std::vector edges, std::vector splits) +{ + std::vector result; + std::vector newEdges; + std::vector edgeSplits; //splits for current edge + int iEdge = 0; //current edge index + int iSplit = 0; //current splitindex + int ii = 0; //i value of current split + int endEdge = edges.size(); + int endSplit = splits.size(); + int imax = std::numeric_limits::max(); + + while ((iEdge < endEdge) ) { + if (iSplit < endSplit) { + ii = splits[iSplit].i; + } else { + ii = imax; + } + if (ii == iEdge) { + edgeSplits.push_back(splits[iSplit]); + iSplit++; + } else if (ii > iEdge) { + if (!edgeSplits.empty()) { //save *iedge's splits + newEdges = split1Edge(edges[iEdge],edgeSplits); + result.insert(result.end(), newEdges.begin(), newEdges.end()); + edgeSplits.clear(); + } else { + result.push_back(edges[iEdge]); //save *iedge + } + iEdge++; //next edge + } else if (iEdge > ii) { + iSplit++; + } + } + + if (!edgeSplits.empty()) { //handle last batch + newEdges = split1Edge(edges[iEdge],edgeSplits); + result.insert(result.end(), newEdges.begin(), newEdges.end()); + edgeSplits.clear(); + } + + return result; +} + + +std::vector DrawProjectSplit::split1Edge(TopoDS_Edge e, std::vector splits) +{ + std::vector result; + if (splits.empty()) { + return result; + } + + BRepAdaptor_Curve adapt(e); + Handle_Geom_Curve c = adapt.Curve().Curve(); + double first = BRepLProp_CurveTool::FirstParameter(adapt); + double last = BRepLProp_CurveTool::LastParameter(adapt); + if (first > last) { + //TODO parms.reverse(); + Base::Console().Message("DPS::split1Edge - edge is backwards!\n"); + return result; + } + std::vector parms; + parms.push_back(first); + for (auto& s:splits) { + parms.push_back(s.param); + } + + parms.push_back(last); + std::vector::iterator pfirst = parms.begin(); + auto parms2 = parms.begin() + 1; + std::vector::iterator psecond = parms2; + std::vector::iterator pstop = parms.end(); + for (; psecond != pstop; pfirst++,psecond++) { + try { + BRepBuilderAPI_MakeEdge mkEdge(c, *pfirst, *psecond); + if (mkEdge.IsDone()) { + TopoDS_Edge e1 = mkEdge.Edge(); + result.push_back(e1); + } + } + catch (Standard_Failure) { + Base::Console().Message("LOG - DPS::split1Edge failed building edge segment\n"); + } + } + return result; +} + +std::vector DrawProjectSplit::sortSplits(std::vector& s, bool ascend) +{ + std::vector sorted = s; + std::sort(sorted.begin(), sorted.end(), DrawProjectSplit::splitCompare); + if (ascend) { + std::reverse(sorted.begin(),sorted.end()); + } + return sorted; +} + +//return true if p1 "is greater than" p2 +/*static*/bool DrawProjectSplit::splitCompare(const splitPoint& p1, const splitPoint& p2) +{ + bool result = false; + if (p1.i > p2.i) { + result = true; + } else if (p1.i < p2.i) { + result = false; + } else if (p1.param > p2.param) { + result = true; + } else if (p1.param < p2.param) { + result = false; + } + return result; +} + +//return true if p1 "is equal to" p2 +/*static*/bool DrawProjectSplit::splitEqual(const splitPoint& p1, const splitPoint& p2) +{ + bool result = false; + if ((p1.i == p2.i) && + (fabs(p1.param - p2.param) < Precision::Confusion())) { + result = true; + } + return result; +} + + diff --git a/src/Mod/TechDraw/App/DrawProjectSplit.h b/src/Mod/TechDraw/App/DrawProjectSplit.h new file mode 100644 index 000000000..d9e708e8d --- /dev/null +++ b/src/Mod/TechDraw/App/DrawProjectSplit.h @@ -0,0 +1,86 @@ +/*************************************************************************** + * Copyright (c) WandererFan (wandererfan@gmail.com) 2016 * + * * + * 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 _DrawProjectSplit_h_ +#define _DrawProjectSplit_h_ + + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +class gp_Pnt; + +namespace TechDrawGeometry +{ +class GeometryObject; +class Vertex; +class BaseGeom; +} + +namespace TechDraw +{ +struct splitPoint { + int i; + Base::Vector3d v; + double param; +}; + +class TechDrawExport DrawProjectSplit +{ +public: + DrawProjectSplit(); + ~DrawProjectSplit(); + +public: + static std::vector getEdgesForWalker(TopoDS_Shape shape, double scale, Base::Vector3d direction); + static TechDrawGeometry::GeometryObject* buildGeometryObject(TopoDS_Shape shape, gp_Pnt& center, Base::Vector3d direction); + + static bool isOnEdge(TopoDS_Edge e, TopoDS_Vertex v, double& param, bool allowEnds = false); + static std::vector splitEdges(std::vector orig, std::vector splits); + static std::vector split1Edge(TopoDS_Edge e, std::vector splitPoints); + static double simpleMinDist(TopoDS_Shape s1, TopoDS_Shape s2); //const; //probably sb static or DrawUtil + + static std::vector sortSplits(std::vector& s, bool ascend); + static bool splitCompare(const splitPoint& p1, const splitPoint& p2); + static bool splitEqual(const splitPoint& p1, const splitPoint& p2); + +protected: + static std::vector getEdges(TechDrawGeometry::GeometryObject* geometryObject); + + +private: + +}; + +typedef App::FeaturePythonT DrawProjectSplitPython; + +} //namespace TechDraw + +#endif // #ifndef _DrawProjectSplit_h_ diff --git a/src/Mod/TechDraw/App/DrawViewCollection.cpp b/src/Mod/TechDraw/App/DrawViewCollection.cpp index 8f5297ca9..47e6b7922 100644 --- a/src/Mod/TechDraw/App/DrawViewCollection.cpp +++ b/src/Mod/TechDraw/App/DrawViewCollection.cpp @@ -118,7 +118,6 @@ void DrawViewCollection::rebuildViewList() short DrawViewCollection::mustExecute() const { - // If Tolerance Property is touched if (Views.isTouched() || Source.isTouched()) { return 1; diff --git a/src/Mod/TechDraw/App/DrawViewDimension.cpp b/src/Mod/TechDraw/App/DrawViewDimension.cpp index dd35cfe2b..13599633e 100644 --- a/src/Mod/TechDraw/App/DrawViewDimension.cpp +++ b/src/Mod/TechDraw/App/DrawViewDimension.cpp @@ -140,7 +140,7 @@ void DrawViewDimension::onChanged(const App::Property* prop) // MeasureType.getValue(),measurement->has3DReferences(),has3DReferences()); clear3DMeasurements(); //Measurement object if (!(References3D.getValues()).empty()) { - set3DMeasurement(References3D.getValues().at(0),References3D.getSubValues()); //Measurement object + setAll3DMeasurement(); } else { if (MeasureType.isValue("True")) { //empty 3dRefs, but True MeasureType.touch(); //run MeasureType logic for this case @@ -156,8 +156,7 @@ void DrawViewDimension::onChanged(const App::Property* prop) void DrawViewDimension::onDocumentRestored() { if (has3DReferences()) { - clear3DMeasurements(); - set3DMeasurement(References3D.getValues().at(0),References3D.getSubValues()); + setAll3DMeasurement(); } } @@ -254,6 +253,7 @@ double DrawViewDimension::getDimValue() const if (!measurement->has3DReferences()) { return result; } + if(Type.isValue("Distance")) { result = measurement->delta().Length(); } else if(Type.isValue("DistanceX")){ @@ -486,14 +486,17 @@ int DrawViewDimension::getRefType2(const std::string g1, const std::string g2) return refType; } -//!add 1 3D measurement Reference -void DrawViewDimension::set3DMeasurement(DocumentObject* const &obj, const std::vector& subElements) +//!add Dimension 3D references to measurement +void DrawViewDimension::setAll3DMeasurement() { - std::vector::const_iterator itSub = subElements.begin(); - for (; itSub != subElements.end(); itSub++) { - //int rc = - static_cast (measurement->addReference3D(obj,(*itSub).c_str())); - } + measurement->clear(); + const std::vector &Objs = References3D.getValues(); + const std::vector &Subs = References3D.getSubValues(); + int end = Objs.size(); + int i = 0; + for ( ; i < end; i++) { + static_cast (measurement->addReference3D(Objs.at(i), Subs.at(i))); + } } //delete all previous measurements diff --git a/src/Mod/TechDraw/App/DrawViewDimension.h b/src/Mod/TechDraw/App/DrawViewDimension.h index 0b1d4a652..4cd9b90ce 100644 --- a/src/Mod/TechDraw/App/DrawViewDimension.h +++ b/src/Mod/TechDraw/App/DrawViewDimension.h @@ -35,6 +35,12 @@ class Measurement; } namespace TechDraw { +class DrawViewPart; + +struct DimRef { + DrawViewPart* part; + std::string sub; +}; class DrawViewPart; @@ -86,6 +92,8 @@ public: static int getRefType1(const std::string s); static int getRefType2(const std::string s1, const std::string s2); int getRefType() const; //Vertex-Vertex, Edge, Edge-Edge + void setAll3DMeasurement(); + void clear3DMeasurements(void); protected: void onChanged(const App::Property* prop); @@ -95,8 +103,6 @@ protected: protected: Measure::Measurement *measurement; - void set3DMeasurement(DocumentObject* const &obj, const std::vector& subElements); - void clear3DMeasurements(void); double dist2Segs(Base::Vector2D s1, Base::Vector2D e1, Base::Vector2D s2, diff --git a/src/Mod/TechDraw/App/DrawViewImage.cpp b/src/Mod/TechDraw/App/DrawViewImage.cpp new file mode 100644 index 000000000..d93fc06a1 --- /dev/null +++ b/src/Mod/TechDraw/App/DrawViewImage.cpp @@ -0,0 +1,98 @@ +/*************************************************************************** + * Copyright (c) 2016 WandererFan (wandererfan@gmail.com) * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + + +#include "PreCompiled.h" + +#ifndef _PreComp_ +# include +#endif + +#include +#include +#include + +#include +#include +#include + +#include "DrawViewImage.h" + +using namespace TechDraw; +using namespace std; + + +//=========================================================================== +// DrawViewImage +//=========================================================================== + +PROPERTY_SOURCE(TechDraw::DrawViewImage, TechDraw::DrawView) + + +DrawViewImage::DrawViewImage(void) +{ + static const char *vgroup = "Image"; + + ADD_PROPERTY_TYPE(ImageFile,(""),vgroup,App::Prop_None,"The file containing this bitmap"); + ADD_PROPERTY_TYPE(Width ,(100),vgroup,App::Prop_None,"The width of the image view"); + ADD_PROPERTY_TYPE(Height ,(100),vgroup,App::Prop_None,"The height of the view"); + ScaleType.setValue("Custom"); +} + +DrawViewImage::~DrawViewImage() +{ +} + +void DrawViewImage::onChanged(const App::Property* prop) +{ + if (prop == &ImageFile) { + if (!isRestoring()) { + } + } + TechDraw::DrawView::onChanged(prop); +} + +App::DocumentObjectExecReturn *DrawViewImage::execute(void) +{ + return DrawView::execute(); +} + +QRectF DrawViewImage::getRect() const +{ + QRectF result(0.0,0.0,Width.getValue(),Height.getValue()); + return result; +} + + +// Python Drawing feature --------------------------------------------------------- + +namespace App { +/// @cond DOXERR +PROPERTY_SOURCE_TEMPLATE(TechDraw::DrawViewImagePython, TechDraw::DrawViewImage) +template<> const char* TechDraw::DrawViewImagePython::getViewProviderName(void) const { + return "TechDrawGui::ViewProviderImage"; +} +/// @endcond + +// explicit template instantiation +template class TechDrawExport FeaturePythonT; +} diff --git a/src/Mod/TechDraw/App/DrawViewImage.h b/src/Mod/TechDraw/App/DrawViewImage.h new file mode 100644 index 000000000..9f241138e --- /dev/null +++ b/src/Mod/TechDraw/App/DrawViewImage.h @@ -0,0 +1,74 @@ +/*************************************************************************** + * Copyright (c) 2016 WandererFan (wandererfan@gmail.com) * + * * + * 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 _DrawViewImage_h_ +#define _DrawViewImage_h_ + +#include +#include +#include +#include "DrawView.h" +#include + +#include + +namespace TechDraw +{ + + +class TechDrawExport DrawViewImage : public TechDraw::DrawView +{ + PROPERTY_HEADER(TechDraw::DrawViewImage); + +public: + /// Constructor + DrawViewImage(void); + virtual ~DrawViewImage(); + + App::PropertyFile ImageFile; + App::PropertyFloat Width; + App::PropertyFloat Height; + + /** @name methods overide Feature */ + //@{ + /// recalculate the Feature + virtual App::DocumentObjectExecReturn *execute(void); + //@} + + /// returns the type name of the ViewProvider + virtual const char* getViewProviderName(void) const { + return "TechDrawGui::ViewProviderImage"; + } + virtual QRectF getRect() const; + +protected: + virtual void onChanged(const App::Property* prop); + Base::BoundBox3d bbox; +}; + +typedef App::FeaturePythonT DrawViewImagePython; + + +} //namespace TechDraw + + +#endif diff --git a/src/Mod/TechDraw/App/DrawViewMulti.cpp b/src/Mod/TechDraw/App/DrawViewMulti.cpp new file mode 100644 index 000000000..6ae44542e --- /dev/null +++ b/src/Mod/TechDraw/App/DrawViewMulti.cpp @@ -0,0 +1,176 @@ +/*************************************************************************** + * Copyright (c) WandererFan (wandererfan@gmail.com) 2016 * + * * + * 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 + +#endif + +#include + +# include +# include + +#include +#include +#include +#include +#include +#include + +#include + +#include "Geometry.h" +#include "GeometryObject.h" +#include "DrawViewMulti.h" + +using namespace TechDraw; +using namespace std; + + +//=========================================================================== +// DrawViewMulti +//=========================================================================== + +PROPERTY_SOURCE(TechDraw::DrawViewMulti, TechDraw::DrawViewPart) + +DrawViewMulti::DrawViewMulti() +{ + static const char *group = "Projection"; + + //properties that affect Geometry + ADD_PROPERTY_TYPE(Sources ,(0),group,App::Prop_None,"3D Shapes to view"); + + //Source is replaced by Sources in Multi + Source.setStatus(App::Property::ReadOnly,true); + + geometryObject = nullptr; +} + +DrawViewMulti::~DrawViewMulti() +{ +} + +short DrawViewMulti::mustExecute() const +{ + short result = 0; + if (!isRestoring()) { + result = (Sources.isTouched()); + } + if (result) { + return result; + } + return TechDraw::DrawViewPart::mustExecute(); +} + +void DrawViewMulti::onChanged(const App::Property* prop) +{ + if (!isRestoring()) { + //Base::Console().Message("TRACE - DVM::onChanged(%s) - %s\n",prop->getName(),Label.getValue()); + if (prop == &Sources) { + const std::vector& links = Sources.getValues(); + if (!links.empty()) { + Source.setValue(links.front()); + } + } + } + + DrawViewPart::onChanged(prop); +} + +App::DocumentObjectExecReturn *DrawViewMulti::execute(void) +{ + const std::vector& links = Sources.getValues(); + if (links.empty()) { + Base::Console().Log("INFO - DVM::execute - No Sources - creation?\n"); + return DrawViewPart::execute(); + } + + //Base::Console().Message("TRACE - DVM::execute() - %s/%s\n",getNameInDocument(),Label.getValue()); + + (void) DrawView::execute(); //make sure Scale is up to date + + BRep_Builder builder; + TopoDS_Compound comp; + builder.MakeCompound(comp); + for (auto& l:links) { + const Part::TopoShape &partTopo = static_cast(l)->Shape.getShape(); + BRepBuilderAPI_Copy BuilderCopy(partTopo.getShape()); + TopoDS_Shape shape = BuilderCopy.Shape(); + builder.Add(comp, shape); + } + m_compound = comp; + + gp_Pnt inputCenter; + try { + inputCenter = TechDrawGeometry::findCentroid(comp, + Direction.getValue()); + TopoDS_Shape mirroredShape = TechDrawGeometry::mirrorShape(comp, + inputCenter, + Scale.getValue()); + geometryObject = buildGeometryObject(mirroredShape,inputCenter); + +#if MOD_TECHDRAW_HANDLE_FACES + extractFaces(); +#endif //#if MOD_TECHDRAW_HANDLE_FACES + } + catch (Standard_Failure) { + Handle_Standard_Failure e1 = Standard_Failure::Caught(); + Base::Console().Log("LOG - DVM::execute - projection failed for %s - %s **\n",getNameInDocument(),e1->GetMessageString()); + return new App::DocumentObjectExecReturn(e1->GetMessageString()); + } + + return App::DocumentObject::StdReturn; +} + +// Python Drawing feature --------------------------------------------------------- + +namespace App { +/// @cond DOXERR +PROPERTY_SOURCE_TEMPLATE(TechDraw::DrawViewMultiPython, TechDraw::DrawViewMulti) +template<> const char* TechDraw::DrawViewMultiPython::getViewProviderName(void) const { + return "TechDrawGui::ViewProviderViewProviderViewPart"; +} +/// @endcond + +// explicit template instantiation +template class TechDrawExport FeaturePythonT; +} diff --git a/src/Mod/TechDraw/App/DrawViewMulti.h b/src/Mod/TechDraw/App/DrawViewMulti.h new file mode 100644 index 000000000..481026af6 --- /dev/null +++ b/src/Mod/TechDraw/App/DrawViewMulti.h @@ -0,0 +1,85 @@ +/*************************************************************************** + * Copyright (c) Jürgen Riegel (juergen.riegel@web.de) 2007 * + * Copyright (c) Luke Parry (l.parry@warwick.ac.uk) 2013 * + * Copyright (c) WandererFan (wandererfan@gmail.com) 2016 * + * 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 _DrawViewMulti_h_ +#define _DrawViewMulti_h_ + +#include +#include +#include +#include +#include + +#include + +#include "DrawViewPart.h" + +class gp_Pln; +class TopoDS_Face; + +namespace TechDrawGeometry +{ +//class Face; +} + +namespace TechDraw +{ + + +/** Base class of all View Features in the drawing module + */ +class TechDrawExport DrawViewMulti : public DrawViewPart +{ + PROPERTY_HEADER(Part::DrawViewMulti); + +public: + /// Constructor + DrawViewMulti(void); + virtual ~DrawViewMulti(); + + App::PropertyLinkList Sources; + + virtual short mustExecute() const; + /** @name methods overide Feature */ + //@{ + /// recalculate the Feature + virtual App::DocumentObjectExecReturn *execute(void); + virtual void onChanged(const App::Property* prop); + //@} + + /// returns the type name of the ViewProvider + virtual const char* getViewProviderName(void) const { + return "TechDrawGui::ViewProviderViewPart"; + } + +protected: + TopoDS_Compound m_compound; + +// void getParameters(void); +}; + +typedef App::FeaturePythonT DrawViewMultiPython; + +} //namespace TechDraw + +#endif diff --git a/src/Mod/TechDraw/App/DrawViewPart.cpp b/src/Mod/TechDraw/App/DrawViewPart.cpp index 4a4ab5f51..7dbee7049 100644 --- a/src/Mod/TechDraw/App/DrawViewPart.cpp +++ b/src/Mod/TechDraw/App/DrawViewPart.cpp @@ -95,7 +95,6 @@ using namespace std; // DrawViewPart //=========================================================================== -App::PropertyFloatConstraint::Constraints DrawViewPart::floatRange = {0.01f,5.0f,0.05f}; PROPERTY_SOURCE(TechDraw::DrawViewPart, TechDraw::DrawView) @@ -108,17 +107,13 @@ DrawViewPart::DrawViewPart(void) : geometryObject(0) //properties that affect Geometry ADD_PROPERTY_TYPE(Source ,(0),group,App::Prop_None,"3D Shape to view"); ADD_PROPERTY_TYPE(Direction ,(0,0,1.0) ,group,App::Prop_None,"Projection direction. The direction you are looking from."); -// ADD_PROPERTY_TYPE(XAxisDirection ,(1,0,0) ,group,App::Prop_None,"Where to place projection's XAxis (rotation)"); - ADD_PROPERTY_TYPE(Tolerance,(0.05f),group,App::Prop_None,"Internal tolerance for calculations"); - Tolerance.setConstraints(&floatRange); //properties that affect Appearance //visible outline ADD_PROPERTY_TYPE(SmoothVisible ,(false),sgroup,App::Prop_None,"Visible Smooth lines on/off"); ADD_PROPERTY_TYPE(SeamVisible ,(false),sgroup,App::Prop_None,"Visible Seam lines on/off"); ADD_PROPERTY_TYPE(IsoVisible ,(false),sgroup,App::Prop_None,"Visible Iso u,v lines on/off"); - ADD_PROPERTY_TYPE(HardHidden ,(false),sgroup,App::Prop_None,"Hidden Hard lines on/off"); // and outline - //hidden outline + ADD_PROPERTY_TYPE(HardHidden ,(false),sgroup,App::Prop_None,"Hidden Hard lines on/off"); ADD_PROPERTY_TYPE(SmoothHidden ,(false),sgroup,App::Prop_None,"Hidden Smooth lines on/off"); ADD_PROPERTY_TYPE(SeamHidden ,(false),sgroup,App::Prop_None,"Hidden Seam lines on/off"); ADD_PROPERTY_TYPE(IsoHidden ,(false),sgroup,App::Prop_None,"Hidden Iso u,v lines on/off"); @@ -135,7 +130,7 @@ DrawViewPart::DrawViewPart(void) : geometryObject(0) //properties that affect Section Line ADD_PROPERTY_TYPE(ShowSectionLine ,(true) ,sgroup,App::Prop_None,"Show/hide section line if applicable"); - geometryObject = new TechDrawGeometry::GeometryObject(this); + geometryObject = nullptr; getRunControl(); } @@ -162,47 +157,20 @@ App::DocumentObjectExecReturn *DrawViewPart::execute(void) return new App::DocumentObjectExecReturn("FVP - Linked shape object is empty"); } - //Base::Console().Message("TRACE - DVP::execute - %s/%s ScaleType: %s\n",getNameInDocument(),Label.getValue(),ScaleType.getValueAsString()); (void) DrawView::execute(); //make sure Scale is up to date - geometryObject->setTolerance(Tolerance.getValue()); - geometryObject->setScale(Scale.getValue()); - - //TODO: remove these try/catch block when code is stable gp_Pnt inputCenter; - try { - inputCenter = TechDrawGeometry::findCentroid(shape, - Direction.getValue()); - shapeCentroid = Base::Vector3d(inputCenter.X(),inputCenter.Y(),inputCenter.Z()); - } - catch (Standard_Failure) { - Handle_Standard_Failure e1 = Standard_Failure::Caught(); - Base::Console().Log("LOG - DVP::execute - findCentroid failed for %s - %s **\n",getNameInDocument(),e1->GetMessageString()); - return new App::DocumentObjectExecReturn(e1->GetMessageString()); - } + inputCenter = TechDrawGeometry::findCentroid(shape, + Direction.getValue()); + shapeCentroid = Base::Vector3d(inputCenter.X(),inputCenter.Y(),inputCenter.Z()); TopoDS_Shape mirroredShape; - try { - mirroredShape = TechDrawGeometry::mirrorShape(shape, - inputCenter, - Scale.getValue()); - } - catch (Standard_Failure) { - Handle_Standard_Failure e2 = Standard_Failure::Caught(); - Base::Console().Log("LOG - DVP::execute - mirrorShape failed for %s - %s **\n",getNameInDocument(),e2->GetMessageString()); - return new App::DocumentObjectExecReturn(e2->GetMessageString()); - } + mirroredShape = TechDrawGeometry::mirrorShape(shape, + inputCenter, + Scale.getValue()); - try { - geometryObject->setIsoCount(IsoCount.getValue()); - buildGeometryObject(mirroredShape,inputCenter); - } - catch (Standard_Failure) { - Handle_Standard_Failure e3 = Standard_Failure::Caught(); - Base::Console().Log("LOG - DVP::execute - buildGeometryObject failed for %s - %s **\n",getNameInDocument(),e3->GetMessageString()); - return new App::DocumentObjectExecReturn(e3->GetMessageString()); - } + geometryObject = buildGeometryObject(mirroredShape,inputCenter); #if MOD_TECHDRAW_HANDLE_FACES if (handleFaces()) { @@ -238,64 +206,68 @@ short DrawViewPart::mustExecute() const void DrawViewPart::onChanged(const App::Property* prop) { - //Base::Console().Message("TRACE - DVP::onChanged(%s) - %s\n",prop->getName(),Label.getValue()); DrawView::onChanged(prop); //TODO: when scale changes, any Dimensions for this View sb recalculated. DVD should pick this up subject to topological naming issues. } -void DrawViewPart::buildGeometryObject(TopoDS_Shape shape, gp_Pnt& inputCenter) +//note: slightly different than routine with same name in DrawProjectSplit +TechDrawGeometry::GeometryObject* DrawViewPart::buildGeometryObject(TopoDS_Shape shape, gp_Pnt& inputCenter) { - Base::Vector3d baseProjDir = Direction.getValue(); + TechDrawGeometry::GeometryObject* go = new TechDrawGeometry::GeometryObject(getNameInDocument()); + go->setIsoCount(IsoCount.getValue()); + Base::Vector3d baseProjDir = Direction.getValue(); saveParamSpace(baseProjDir); - geometryObject->projectShape(shape, - inputCenter, - Direction.getValue()); - geometryObject->extractGeometry(TechDrawGeometry::ecHARD, //always show the hard&outline visible lines - true); - geometryObject->extractGeometry(TechDrawGeometry::ecOUTLINE, - true); + go->projectShape(shape, + inputCenter, + Direction.getValue()); + go->extractGeometry(TechDrawGeometry::ecHARD, //always show the hard&outline visible lines + true); + go->extractGeometry(TechDrawGeometry::ecOUTLINE, + true); if (SmoothVisible.getValue()) { - geometryObject->extractGeometry(TechDrawGeometry::ecSMOOTH, - true); + go->extractGeometry(TechDrawGeometry::ecSMOOTH, + true); } if (SeamVisible.getValue()) { - geometryObject->extractGeometry(TechDrawGeometry::ecSEAM, - true); + go->extractGeometry(TechDrawGeometry::ecSEAM, + true); } if ((IsoVisible.getValue()) && (IsoCount.getValue() > 0)) { - geometryObject->extractGeometry(TechDrawGeometry::ecUVISO, - true); + go->extractGeometry(TechDrawGeometry::ecUVISO, + true); } if (HardHidden.getValue()) { - geometryObject->extractGeometry(TechDrawGeometry::ecHARD, - false); - geometryObject->extractGeometry(TechDrawGeometry::ecOUTLINE, - false); + go->extractGeometry(TechDrawGeometry::ecHARD, + false); + go->extractGeometry(TechDrawGeometry::ecOUTLINE, + false); } if (SmoothHidden.getValue()) { - geometryObject->extractGeometry(TechDrawGeometry::ecSMOOTH, - false); + go->extractGeometry(TechDrawGeometry::ecSMOOTH, + false); } if (SeamHidden.getValue()) { - geometryObject->extractGeometry(TechDrawGeometry::ecSEAM, - false); + go->extractGeometry(TechDrawGeometry::ecSEAM, + false); } if (IsoHidden.getValue() && (IsoCount.getValue() > 0)) { - geometryObject->extractGeometry(TechDrawGeometry::ecUVISO, - false); + go->extractGeometry(TechDrawGeometry::ecUVISO, + false); } - bbox = geometryObject->calcBoundingBox(); + bbox = go->calcBoundingBox(); + return go; } //! make faces from the existing edge geometry void DrawViewPart::extractFaces() { geometryObject->clearFaceGeom(); - const std::vector& goEdges = geometryObject->getVisibleFaceEdges(); + const std::vector& goEdges = + geometryObject->getVisibleFaceEdges(SmoothVisible.getValue(),SeamVisible.getValue()); std::vector::const_iterator itEdge = goEdges.begin(); std::vector origEdges; for (;itEdge != goEdges.end(); itEdge++) { @@ -356,7 +328,7 @@ void DrawViewPart::extractFaces() } double param = -1; - if (isOnEdge((*itInner),v1,param,false)) { + if (DrawProjectSplit::isOnEdge((*itInner),v1,param,false)) { gp_Pnt pnt1 = BRep_Tool::Pnt(v1); splitPoint s1; s1.i = iInner; @@ -364,7 +336,7 @@ void DrawViewPart::extractFaces() s1.param = param; splits.push_back(s1); } - if (isOnEdge((*itInner),v2,param,false)) { + if (DrawProjectSplit::isOnEdge((*itInner),v2,param,false)) { gp_Pnt pnt2 = BRep_Tool::Pnt(v2); splitPoint s2; s2.i = iInner; @@ -375,10 +347,10 @@ void DrawViewPart::extractFaces() } //inner loop } //outer loop - std::vector sorted = sortSplits(splits,true); - auto last = std::unique(sorted.begin(), sorted.end(), DrawViewPart::splitEqual); //duplicates to back + std::vector sorted = DrawProjectSplit::sortSplits(splits,true); + auto last = std::unique(sorted.begin(), sorted.end(), DrawProjectSplit::splitEqual); //duplicates to back sorted.erase(last, sorted.end()); //remove dupls - std::vector newEdges = splitEdges(faceEdges,sorted); + std::vector newEdges = DrawProjectSplit::splitEdges(faceEdges,sorted); if (newEdges.empty()) { Base::Console().Log("LOG - DVP::extractFaces - no newEdges\n"); @@ -408,247 +380,6 @@ void DrawViewPart::extractFaces() } } -double DrawViewPart::simpleMinDist(TopoDS_Shape s1, TopoDS_Shape s2) -{ - Standard_Real minDist = -1; - - BRepExtrema_DistShapeShape extss(s1, s2); - if (!extss.IsDone()) { - Base::Console().Message("DVP - BRepExtrema_DistShapeShape failed"); - return -1; - } - int count = extss.NbSolution(); - if (count != 0) { - minDist = extss.Value(); - } else { - minDist = -1; - } - return minDist; -} - -//this routine is the big time consumer. gets called many times (and is slow?)) -//note param gets modified here -bool DrawViewPart::isOnEdge(TopoDS_Edge e, TopoDS_Vertex v, double& param, bool allowEnds) -{ - bool result = false; - bool outOfBox = false; - param = -2; - - //eliminate obvious cases - Bnd_Box sBox; - BRepBndLib::Add(e, sBox); - sBox.SetGap(0.1); - if (sBox.IsVoid()) { - Base::Console().Message("DVP::isOnEdge - Bnd_Box is void for %s\n",getNameInDocument()); - } else { - gp_Pnt pt = BRep_Tool::Pnt(v); - if (sBox.IsOut(pt)) { - outOfBox = true; - } - } - if (!outOfBox) { - if (m_interAlgo == 1) { - //1) using projPointOnCurve. roughly similar to dist to shape w/ bndbox. hangs(?) w/o bndbox - try { - gp_Pnt pt = BRep_Tool::Pnt(v); - BRepAdaptor_Curve adapt(e); - Handle_Geom_Curve c = adapt.Curve().Curve(); - GeomAPI_ProjectPointOnCurve proj(pt,c); - int n = proj.NbPoints(); - if (n > 0) { - if (proj.LowerDistance() < Precision::Confusion()) { - param = proj.LowerDistanceParameter(); - result = true; - } - if (result) { - TopoDS_Vertex v1 = TopExp::FirstVertex(e); - TopoDS_Vertex v2 = TopExp::LastVertex(e); - if (DrawUtil::isSamePoint(v,v1) || DrawUtil::isSamePoint(v,v2)) { - if (!allowEnds) { - result = false; - } - } - } - } - } - catch (Standard_Failure) { - Handle_Standard_Failure e = Standard_Failure::Caught(); //no perp projection - } - } else if (m_interAlgo == 2) { //can't provide param as is - double dist = simpleMinDist(v,e); - if (dist < 0.0) { - Base::Console().Error("DVP::isOnEdge - simpleMinDist failed: %.3f\n",dist); - result = false; - } else if (dist < Precision::Confusion()) { - const gp_Pnt pt = BRep_Tool::Pnt(v); //have to duplicate method 3 to get param - BRepAdaptor_Curve adapt(e); - const Handle_Geom_Curve c = adapt.Curve().Curve(); - double maxDist = 0.000001; //magic number. less than this gives false positives. - //bool found = - (void) GeomLib_Tool::Parameter(c,pt,maxDist,param); //already know point it on curve - result = true; - } - if (result) { - TopoDS_Vertex v1 = TopExp::FirstVertex(e); - TopoDS_Vertex v2 = TopExp::LastVertex(e); - if (DrawUtil::isSamePoint(v,v1) || DrawUtil::isSamePoint(v,v2)) { - if (!allowEnds) { - result = false; - } - } - } - } else if (m_interAlgo == 3) { - const gp_Pnt pt = BRep_Tool::Pnt(v); - BRepAdaptor_Curve adapt(e); - const Handle_Geom_Curve c = adapt.Curve().Curve(); - double par = -1; - double maxDist = 0.000001; //magic number. less than this gives false positives. - bool found = GeomLib_Tool::Parameter(c,pt,maxDist,par); - if (found) { - result = true; - param = par; - TopoDS_Vertex v1 = TopExp::FirstVertex(e); - TopoDS_Vertex v2 = TopExp::LastVertex(e); - if (DrawUtil::isSamePoint(v,v1) || DrawUtil::isSamePoint(v,v2)) { - if (!allowEnds) { - result = false; - } - } - } - } - } //!outofbox - return result; -} - -std::vector DrawViewPart::splitEdges(std::vector edges, std::vector splits) -{ - std::vector result; - std::vector newEdges; - std::vector edgeSplits; //splits for current edge - int iEdge = 0; //current edge index - int iSplit = 0; //current splitindex - int ii = 0; //i value of current split - int endEdge = edges.size(); - int endSplit = splits.size(); - int imax = std::numeric_limits::max(); - - while ((iEdge < endEdge) ) { - if (iSplit < endSplit) { - ii = splits[iSplit].i; - } else { - ii = imax; - } - if (ii == iEdge) { - edgeSplits.push_back(splits[iSplit]); - iSplit++; - continue; - } - - if (ii > iEdge) { - if (!edgeSplits.empty()) { //save *iedge's splits - newEdges = split1Edge(edges[iEdge],edgeSplits); - result.insert(result.end(), newEdges.begin(), newEdges.end()); - edgeSplits.clear(); - } else { - result.push_back(edges[iEdge]); //save *iedge - } - iEdge++; //next edge - continue; - } - - if (iEdge > ii) { - iSplit++; - continue; - } - } - if (!edgeSplits.empty()) { //handle last batch - newEdges = split1Edge(edges[iEdge],edgeSplits); - result.insert(result.end(), newEdges.begin(), newEdges.end()); - edgeSplits.clear(); - } - - return result; -} - -std::vector DrawViewPart::split1Edge(TopoDS_Edge e, std::vector splits) -{ - //Base::Console().Message("DVP::split1Edge - splits: %d\n",splits.size()); - std::vector result; - if (splits.empty()) { - return result; - } - - BRepAdaptor_Curve adapt(e); - Handle_Geom_Curve c = adapt.Curve().Curve(); - double first = BRepLProp_CurveTool::FirstParameter(adapt); - double last = BRepLProp_CurveTool::LastParameter(adapt); - if (first > last) { - //TODO parms.reverse(); - Base::Console().Message("DVP::split1Edge - edge is backwards!\n"); - return result; - } - std::vector parms; - parms.push_back(first); - for (auto& s:splits) { - parms.push_back(s.param); - } - - parms.push_back(last); - std::vector::iterator pfirst = parms.begin(); - auto parms2 = parms.begin() + 1; - std::vector::iterator psecond = parms2; - std::vector::iterator pstop = parms.end(); - for (; psecond != pstop; pfirst++,psecond++) { - try { - BRepBuilderAPI_MakeEdge mkEdge(c, *pfirst, *psecond); - if (mkEdge.IsDone()) { - TopoDS_Edge e1 = mkEdge.Edge(); - result.push_back(e1); - } - } - catch (Standard_Failure) { - Base::Console().Message("LOG - DVP::split1Edge failed building edge segment\n"); - } - } - return result; -} - -std::vector DrawViewPart::sortSplits(std::vector& s, bool ascend) -{ - std::vector sorted = s; - std::sort(sorted.begin(), sorted.end(), DrawViewPart::splitCompare); - if (ascend) { - std::reverse(sorted.begin(),sorted.end()); - } - return sorted; -} - -//return true if p1 "is greater than" p2 -/*static*/bool DrawViewPart::splitCompare(const splitPoint& p1, const splitPoint& p2) -{ - bool result = false; - if (p1.i > p2.i) { - result = true; - } else if (p1.i < p2.i) { - result = false; - } else if (p1.param > p2.param) { - result = true; - } else if (p1.param < p2.param) { - result = false; - } - return result; -} - -//return true if p1 "is equal to" p2 -/*static*/bool DrawViewPart::splitEqual(const splitPoint& p1, const splitPoint& p2) -{ - bool result = false; - if ((p1.i == p2.i) && - (fabs(p1.param - p2.param) < Precision::Confusion())) { - result = true; - } - return result; -} std::vector DrawViewPart::getHatches() const { @@ -763,6 +494,9 @@ Base::Vector3d DrawViewPart::projectPoint(const Base::Vector3d& pt) const bool DrawViewPart::hasGeometry(void) const { bool result = false; + if (geometryObject == nullptr) { + return result; + } const std::vector &verts = getVertexGeometry(); const std::vector &edges = getEdgeGeometry(); if (verts.empty() && @@ -802,18 +536,15 @@ std::vector DrawViewPart::getSectionRefs(void) const const std::vector DrawViewPart::getVisibleFaceEdges() const { - return geometryObject->getVisibleFaceEdges(); + return geometryObject->getVisibleFaceEdges(SmoothVisible.getValue(),SeamVisible.getValue()); } void DrawViewPart::getRunControl() { Base::Reference hGrp = App::GetApplication().GetUserParameter() .GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/TechDraw/RunControl"); - m_interAlgo = hGrp->GetInt("InterAlgo", 2l); m_sectionEdges = hGrp->GetBool("ShowSectionEdges", 1l); m_handleFaces = hGrp->GetBool("HandleFaces", 1l); -// Base::Console().Message("TRACE - DVP::getRunControl - interAlgo: %ld sectionFaces: %ld handleFaces: %ld\n", -// m_interAlgo,m_sectionEdges,m_handleFaces); } bool DrawViewPart::handleFaces(void) diff --git a/src/Mod/TechDraw/App/DrawViewPart.h b/src/Mod/TechDraw/App/DrawViewPart.h index 93330b235..90936e0d3 100644 --- a/src/Mod/TechDraw/App/DrawViewPart.h +++ b/src/Mod/TechDraw/App/DrawViewPart.h @@ -32,12 +32,12 @@ #include #include #include -#include "DrawView.h" #include #include -//#include "GeometryObject.h" +#include "DrawView.h" +#include "DrawProjectSplit.h" class gp_Pnt; @@ -55,11 +55,7 @@ class DrawHatch; namespace TechDraw { -struct splitPoint { - int i; - Base::Vector3d v; - double param; -}; + class DrawViewSection; class TechDrawExport DrawViewPart : public DrawView @@ -72,7 +68,6 @@ public: App::PropertyLink Source; //Part Feature App::PropertyVector Direction; //TODO: Rename to YAxisDirection or whatever this actually is (ProjectionDirection) - //App::PropertyVector XAxisDirection; App::PropertyBool SeamVisible; App::PropertyBool SmoothVisible; //App::PropertyBool OutlinesVisible; @@ -90,7 +85,6 @@ public: App::PropertyFloat IsoWidth; App::PropertyBool ArcCenterMarks; App::PropertyFloat CenterScale; - App::PropertyFloatConstraint Tolerance; App::PropertyBool HorizCenterLine; App::PropertyBool VertCenterLine; App::PropertyBool ShowSectionLine; @@ -144,31 +138,21 @@ protected: Base::BoundBox3d bbox; void onChanged(const App::Property* prop); - void buildGeometryObject(TopoDS_Shape shape, gp_Pnt& center); + TechDrawGeometry::GeometryObject* buildGeometryObject(TopoDS_Shape shape, gp_Pnt& center); void extractFaces(); - bool isOnEdge(TopoDS_Edge e, TopoDS_Vertex v, double& param, bool allowEnds = false); - std::vector splitEdges(std::vector orig, std::vector splits); - std::vector split1Edge(TopoDS_Edge e, std::vector splitPoints); - double simpleMinDist(TopoDS_Shape s1, TopoDS_Shape s2); //const; //probably sb static or DrawUtil - //Projection parameter space void saveParamSpace(const Base::Vector3d& direction); Base::Vector3d uDir; //paperspace X Base::Vector3d vDir; //paperspace Y Base::Vector3d wDir; //paperspace Z Base::Vector3d shapeCentroid; - std::vector sortSplits(std::vector& s, bool ascend); - static bool splitCompare(const splitPoint& p1, const splitPoint& p2); - static bool splitEqual(const splitPoint& p1, const splitPoint& p2); void getRunControl(void); - long int m_interAlgo; bool m_sectionEdges; bool m_handleFaces; private: - static App::PropertyFloatConstraint::Constraints floatRange; }; diff --git a/src/Mod/TechDraw/App/DrawViewSection.cpp b/src/Mod/TechDraw/App/DrawViewSection.cpp index 29b94c2bd..21bf0aa14 100644 --- a/src/Mod/TechDraw/App/DrawViewSection.cpp +++ b/src/Mod/TechDraw/App/DrawViewSection.cpp @@ -74,6 +74,7 @@ #include "Geometry.h" #include "GeometryObject.h" #include "EdgeWalker.h" +#include "DrawProjectSplit.h" #include "DrawViewSection.h" using namespace TechDraw; @@ -219,9 +220,6 @@ App::DocumentObjectExecReturn *DrawViewSection::execute(void) return DrawView::execute(); } - geometryObject->setTolerance(Tolerance.getValue()); - geometryObject->setScale(Scale.getValue()); - gp_Pnt inputCenter; try { inputCenter = TechDrawGeometry::findCentroid(rawShape, @@ -229,7 +227,7 @@ App::DocumentObjectExecReturn *DrawViewSection::execute(void) TopoDS_Shape mirroredShape = TechDrawGeometry::mirrorShape(rawShape, inputCenter, Scale.getValue()); - buildGeometryObject(mirroredShape,inputCenter); //this is original shape after cut by section prism + geometryObject = buildGeometryObject(mirroredShape,inputCenter); //this is original shape after cut by section prism #if MOD_TECHDRAW_HANDLE_FACES extractFaces(); diff --git a/src/Mod/TechDraw/App/GeometryObject.cpp b/src/Mod/TechDraw/App/GeometryObject.cpp index 2b0c92b4f..879c8c893 100644 --- a/src/Mod/TechDraw/App/GeometryObject.cpp +++ b/src/Mod/TechDraw/App/GeometryObject.cpp @@ -38,10 +38,8 @@ #include #include #include -//#include #include #include -//#include #include #include #include @@ -69,8 +67,6 @@ #include "GeometryObject.h" #include "DrawViewPart.h" -//#include - using namespace TechDrawGeometry; using namespace TechDraw; using namespace std; @@ -80,11 +76,9 @@ struct EdgePoints { TopoDS_Edge edge; }; - -GeometryObject::GeometryObject(DrawViewPart* parent) : - Tolerance(0.05f), +GeometryObject::GeometryObject(std::string parent) : Scale(1.f), - m_parent(parent), + m_parentName(parent), m_isoCount(0) { } @@ -94,21 +88,18 @@ GeometryObject::~GeometryObject() clear(); } -void GeometryObject::setTolerance(double value) -{ - Tolerance = value; -} - void GeometryObject::setScale(double value) { Scale = value; } -const std::vector GeometryObject::getVisibleFaceEdges() const + +const std::vector GeometryObject::getVisibleFaceEdges(const bool smooth, const bool seam) const { std::vector result; - bool smoothOK = m_parent->SmoothVisible.getValue(); - bool seamOK = m_parent->SeamVisible.getValue(); + bool smoothOK = smooth; + bool seamOK = seam; + for (auto& e:edgeGeom) { if (e->visible) { switch (e->classOfEdge) { @@ -184,7 +175,7 @@ void GeometryObject::projectShape(const TopoDS_Shape& input, auto end = chrono::high_resolution_clock::now(); auto diff = end - start; double diffOut = chrono::duration (diff).count(); - Base::Console().Log("TIMING - %s GO spent: %.3f millisecs in HLRBRep_Algo & co\n",m_parent->getNameInDocument(),diffOut); + Base::Console().Log("TIMING - %s GO spent: %.3f millisecs in HLRBRep_Algo & co\n",m_parentName.c_str(),diffOut); try { HLRBRep_HLRToShape hlrToShape(brep_hlr); @@ -297,7 +288,6 @@ void GeometryObject::addGeomFromCompound(TopoDS_Shape edgeCompound, edgeClass ca //add vertices of new edge if not already in list if (visible) { BaseGeom* lastAdded = edgeGeom.back(); - //if (edgeGeom.empty()) {horrible_death();} //back() undefined behavior (can't happen? baseFactory always returns a Base?) bool v1Add = true, v2Add = true; bool c1Add = true; TechDrawGeometry::Vertex* v1 = new TechDrawGeometry::Vertex(lastAdded->getStartPoint()); @@ -754,24 +744,22 @@ TopoDS_Shape TechDrawGeometry::mirrorShape(const TopoDS_Shape &input, return transShape; } -/// debug functions -/* TODO: Clean this up when faces are actually working properly... - -void debugEdge(const TopoDS_Edge &e) - +//!scales a shape about a origin +TopoDS_Shape TechDrawGeometry::scaleShape(const TopoDS_Shape &input, + double scale) { + TopoDS_Shape transShape; + try { + gp_Trsf scaleTransform; + scaleTransform.SetScale(gp_Pnt(0,0,0), scale); - gp_Pnt p0 = BRep_Tool::Pnt(TopExp::FirstVertex(e)); - - gp_Pnt p1 = BRep_Tool::Pnt(TopExp::LastVertex(e)); - - qDebug()< #include -//#include #include #include @@ -33,7 +32,6 @@ #include #include "Geometry.h" -//#include "DrawViewPart.h" namespace TechDraw { @@ -48,6 +46,8 @@ namespace TechDrawGeometry TopoDS_Shape TechDrawExport mirrorShape(const TopoDS_Shape &input, const gp_Pnt& inputCenter, double scale); +TopoDS_Shape TechDrawExport scaleShape(const TopoDS_Shape &input, + double scale); //! Returns the centroid of shape, as viewed according to direction gp_Pnt TechDrawExport findCentroid(const TopoDS_Shape &shape, @@ -61,12 +61,11 @@ class TechDrawExport GeometryObject { public: /// Constructor - GeometryObject(TechDraw::DrawViewPart* parent); + GeometryObject(std::string parent); virtual ~GeometryObject(); void clear(); - void setTolerance(double value); void setScale(double value); //! Returns 2D bounding box @@ -74,7 +73,7 @@ public: const std::vector & getVertexGeometry() const { return vertexGeom; }; const std::vector & getEdgeGeometry() const { return edgeGeom; }; - const std::vector getVisibleFaceEdges() const; + const std::vector getVisibleFaceEdges(bool smooth, bool seam) const; const std::vector & getFaceGeometry() const { return faceGeom; }; void projectShape(const TopoDS_Shape &input, @@ -84,6 +83,7 @@ public: void addFaceGeom(Face * f); void clearFaceGeom(); void setIsoCount(int i) { m_isoCount = i; } + void setParentName(std::string n); //for debug messages protected: //HLR output @@ -128,10 +128,9 @@ protected: bool findVertex(Base::Vector2D v); - double Tolerance; double Scale; - TechDraw::DrawViewPart* m_parent; + std::string m_parentName; int m_isoCount; }; diff --git a/src/Mod/TechDraw/Gui/AppTechDrawGui.cpp b/src/Mod/TechDraw/Gui/AppTechDrawGui.cpp index dfb5ba097..7a651a47b 100644 --- a/src/Mod/TechDraw/Gui/AppTechDrawGui.cpp +++ b/src/Mod/TechDraw/Gui/AppTechDrawGui.cpp @@ -48,6 +48,8 @@ #include "ViewProviderViewClip.h" #include "ViewProviderHatch.h" #include "ViewProviderSpreadsheet.h" +#include "ViewProviderImage.h" + // use a different name to CreateCommand() void CreateTechDrawCommands(void); @@ -100,6 +102,7 @@ void TechDrawGuiExport initTechDrawGui() TechDrawGui::ViewProviderArch::init(); TechDrawGui::ViewProviderHatch::init(); TechDrawGui::ViewProviderSpreadsheet::init(); + TechDrawGui::ViewProviderImage::init(); // register preferences pages new Gui::PrefPageProducer ("TechDraw"); diff --git a/src/Mod/TechDraw/Gui/CMakeLists.txt b/src/Mod/TechDraw/Gui/CMakeLists.txt index a89b583d4..4c941aed6 100644 --- a/src/Mod/TechDraw/Gui/CMakeLists.txt +++ b/src/Mod/TechDraw/Gui/CMakeLists.txt @@ -103,6 +103,8 @@ SET(TechDrawGuiView_SRCS QGCustomLabel.h QGCustomBorder.cpp QGCustomBorder.h + QGCustomImage.cpp + QGCustomImage.h QGIView.cpp QGIView.h QGIArrow.cpp @@ -135,6 +137,8 @@ SET(TechDrawGuiView_SRCS QGIViewSymbol.h QGIViewSpreadsheet.cpp QGIViewSpreadsheet.h + QGIViewImage.cpp + QGIViewImage.h QGIViewClip.cpp QGIViewClip.h QGIPrimPath.cpp @@ -180,6 +184,8 @@ SET(TechDrawGuiViewProvider_SRCS ViewProviderViewClip.h ViewProviderHatch.cpp ViewProviderHatch.h + ViewProviderImage.cpp + ViewProviderImage.h ) SOURCE_GROUP("Mod" FILES ${TechDrawGui_SRCS}) diff --git a/src/Mod/TechDraw/Gui/Command.cpp b/src/Mod/TechDraw/Gui/Command.cpp index a31f55c47..6ec8a21d8 100644 --- a/src/Mod/TechDraw/Gui/Command.cpp +++ b/src/Mod/TechDraw/Gui/Command.cpp @@ -63,6 +63,7 @@ #include #include #include +#include #include #include "DrawGuiUtil.h" @@ -442,6 +443,58 @@ bool CmdTechDrawProjGroup::isActive(void) return (havePage && !taskInProgress); } +//=========================================================================== +// TechDraw_NewMulti +//=========================================================================== + +DEF_STD_CMD_A(CmdTechDrawNewMulti); + +CmdTechDrawNewMulti::CmdTechDrawNewMulti() + : Command("TechDraw_NewMulti") +{ + sAppModule = "TechDraw"; + sGroup = QT_TR_NOOP("TechDraw"); + sMenuText = QT_TR_NOOP("Insert multi-part view in drawing"); + sToolTipText = QT_TR_NOOP("Insert a new View of a multiple Parts in the active drawing"); + sWhatsThis = "TechDraw_NewMulti"; + sStatusTip = sToolTipText; + sPixmap = "actions/techdraw-multiview"; +} + +void CmdTechDrawNewMulti::activated(int iMsg) +{ + Q_UNUSED(iMsg); + TechDraw::DrawPage* page = DrawGuiUtil::findPage(this); + if (!page) { + return; + } + + const std::vector& shapes = getSelection().getObjectsOfType(Part::Feature::getClassTypeId()); + if (shapes.empty()) { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), + QObject::tr("Select at least 1 Part object.")); + return; + } + + std::string PageName = page->getNameInDocument(); + + Gui::WaitCursor wc; + + openCommand("Create view"); + std::string FeatName = getUniqueObjectName("MultiView"); + doCommand(Doc,"App.activeDocument().addObject('TechDraw::DrawViewMulti','%s')",FeatName.c_str()); + App::DocumentObject *docObj = getDocument()->getObject(FeatName.c_str()); + auto multiView( static_cast(docObj) ); + multiView->Sources.setValues(shapes); + doCommand(Doc,"App.activeDocument().%s.addView(App.activeDocument().%s)",PageName.c_str(),FeatName.c_str()); + updateActive(); + commitCommand(); +} + +bool CmdTechDrawNewMulti::isActive(void) +{ + return DrawGuiUtil::needPage(this); +} //=========================================================================== // TechDraw_Annotation @@ -826,7 +879,7 @@ void CmdTechDrawArchView::activated(int iMsg) QObject::tr("The selected object is not an Arch Section Plane.")); return; } - + std::string PageName = page->getNameInDocument(); std::string FeatName = getUniqueObjectName("ArchView"); @@ -957,6 +1010,7 @@ void CreateTechDrawCommands(void) rcCmdMgr.addCommand(new CmdTechDrawNewPage()); rcCmdMgr.addCommand(new CmdTechDrawNewView()); rcCmdMgr.addCommand(new CmdTechDrawNewViewSection()); + rcCmdMgr.addCommand(new CmdTechDrawNewMulti()); rcCmdMgr.addCommand(new CmdTechDrawProjGroup()); rcCmdMgr.addCommand(new CmdTechDrawAnnotation()); rcCmdMgr.addCommand(new CmdTechDrawClip()); diff --git a/src/Mod/TechDraw/Gui/CommandCreateDims.cpp b/src/Mod/TechDraw/Gui/CommandCreateDims.cpp index 0bc328418..b6e5e5d45 100644 --- a/src/Mod/TechDraw/Gui/CommandCreateDims.cpp +++ b/src/Mod/TechDraw/Gui/CommandCreateDims.cpp @@ -865,14 +865,20 @@ void CmdTechDrawLinkDimension::activated(int iMsg) return; std::vector selection = getSelection().getSelectionEx(); - Part::Feature* obj3D = 0; + + App::DocumentObject* obj3D = 0; + std::vector parts; std::vector subs; std::vector::iterator itSel = selection.begin(); for (; itSel != selection.end(); itSel++) { if ((*itSel).getObject()->isDerivedFrom(Part::Feature::getClassTypeId())) { - obj3D = static_cast ((*itSel).getObject()); - subs = (*itSel).getSubNames(); + obj3D = ((*itSel).getObject()); + std::vector subList = (*itSel).getSubNames(); + for (auto& s:subList) { + parts.push_back(obj3D); + subs.push_back(s); + } } } @@ -890,7 +896,7 @@ void CmdTechDrawLinkDimension::activated(int iMsg) // dialog to select the Dimension to link - Gui::Control().showDialog(new TaskDlgLinkDim(obj3D,subs,page)); + Gui::Control().showDialog(new TaskDlgLinkDim(parts,subs,page)); page->getDocument()->recompute(); //still need to recompute in Gui. why? } diff --git a/src/Mod/TechDraw/Gui/CommandDecorate.cpp b/src/Mod/TechDraw/Gui/CommandDecorate.cpp index 60e3cb366..322499d15 100644 --- a/src/Mod/TechDraw/Gui/CommandDecorate.cpp +++ b/src/Mod/TechDraw/Gui/CommandDecorate.cpp @@ -126,6 +126,58 @@ bool CmdTechDrawNewHatch::isActive(void) return (havePage && haveView); } +//=========================================================================== +// TechDraw_Image +//=========================================================================== + +DEF_STD_CMD_A(CmdTechDrawImage); + +CmdTechDrawImage::CmdTechDrawImage() + : Command("TechDraw_Image") +{ + // setting the Gui eye-candy + sGroup = QT_TR_NOOP("TechDraw"); + sMenuText = QT_TR_NOOP("Insert bitmap image"); + sToolTipText = QT_TR_NOOP("Inserts a bitmap from a file in the active drawing"); + sWhatsThis = "TechDraw_Image"; + sStatusTip = QT_TR_NOOP("Inserts a bitmap from a file in the active drawing"); + sPixmap = "actions/techdraw-image"; +} + +void CmdTechDrawImage::activated(int iMsg) +{ + Q_UNUSED(iMsg); + TechDraw::DrawPage* page = DrawGuiUtil::findPage(this); + if (!page) { + return; + } + std::string PageName = page->getNameInDocument(); + + // Reading an image + std::string defaultDir = App::Application::getResourceDir(); + QString qDir = QString::fromUtf8(defaultDir.data(),defaultDir.size()); + QString fileName = Gui::FileDialog::getOpenFileName(Gui::getMainWindow(), + QString::fromUtf8(QT_TR_NOOP("Select an Image File")), + qDir, + QString::fromUtf8(QT_TR_NOOP("Image (*.png *.jpg *.jpeg)"))); + + if (!fileName.isEmpty()) + { + std::string FeatName = getUniqueObjectName("Image"); + openCommand("Create Image"); + doCommand(Doc,"App.activeDocument().addObject('TechDraw::DrawViewImage','%s')",FeatName.c_str()); + doCommand(Doc,"App.activeDocument().%s.ImageFile = '%s'",FeatName.c_str(),fileName.toUtf8().constData()); + doCommand(Doc,"App.activeDocument().%s.addView(App.activeDocument().%s)",PageName.c_str(),FeatName.c_str()); + updateActive(); + commitCommand(); + } +} + +bool CmdTechDrawImage::isActive(void) +{ + return DrawGuiUtil::needPage(this); +} + //=========================================================================== // TechDraw_ToggleFrame //=========================================================================== @@ -178,6 +230,7 @@ void CreateTechDrawCommandsDecorate(void) Gui::CommandManager &rcCmdMgr = Gui::Application::Instance->commandManager(); rcCmdMgr.addCommand(new CmdTechDrawNewHatch()); + rcCmdMgr.addCommand(new CmdTechDrawImage()); rcCmdMgr.addCommand(new CmdTechDrawToggleFrame()); } diff --git a/src/Mod/TechDraw/Gui/MDIViewPage.cpp b/src/Mod/TechDraw/Gui/MDIViewPage.cpp index 1e5845a52..545c8f988 100644 --- a/src/Mod/TechDraw/Gui/MDIViewPage.cpp +++ b/src/Mod/TechDraw/Gui/MDIViewPage.cpp @@ -75,6 +75,7 @@ #include #include #include +#include #include "QGIDrawingTemplate.h" #include "QGIView.h" @@ -315,6 +316,9 @@ bool MDIViewPage::attachView(App::DocumentObject *obj) } else if (typeId.isDerivedFrom(TechDraw::DrawViewSpreadsheet::getClassTypeId()) ) { qview = m_view->addDrawViewSpreadsheet( static_cast(obj) ); + } else if (typeId.isDerivedFrom(TechDraw::DrawViewImage::getClassTypeId()) ) { + qview = m_view->addDrawViewImage( static_cast(obj) ); + } else if (typeId.isDerivedFrom(TechDraw::DrawHatch::getClassTypeId()) ) { //Hatch is not attached like other Views (since it isn't really a View) return true; diff --git a/src/Mod/TechDraw/Gui/QGCustomImage.cpp b/src/Mod/TechDraw/Gui/QGCustomImage.cpp new file mode 100644 index 000000000..034439144 --- /dev/null +++ b/src/Mod/TechDraw/Gui/QGCustomImage.cpp @@ -0,0 +1,92 @@ +/*************************************************************************** + * Copyright (c) 2016 WandererFan (wandererfan@gmail.com) * + * * + * 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 +#endif + +#include + +#include +#include +#include "QGCustomImage.h" + +using namespace TechDrawGui; + +QGCustomImage::QGCustomImage() +{ + setCacheMode(QGraphicsItem::NoCache); + setAcceptHoverEvents(false); + setFlag(QGraphicsItem::ItemIsSelectable, false); + setFlag(QGraphicsItem::ItemIsMovable, false); + setFlag(QGraphicsItem::ItemSendsGeometryChanges, true); +} + +QGCustomImage::~QGCustomImage() +{ +} + +void QGCustomImage::centerAt(QPointF centerPos) +{ + centerAt(centerPos.x(),centerPos.y()); +} + +void QGCustomImage::centerAt(double cX, double cY) +{ +// QGraphicsItemGroup* g = group(); +// if (g == nullptr) { +// return; +// } + QPointF parentPt(cX,cY); + QPointF myPt = mapFromParent(parentPt); + + QRectF br = boundingRect(); + double width = br.width(); + double height = br.height(); + double newX = width/2.0; + double newY = height/2.0; + QPointF off(myPt.x() - newX,myPt.y() - newY); + setOffset(off); +} + +bool QGCustomImage::load(QString fileSpec) +{ + bool success = true; + QPixmap px(fileSpec); + m_px = px; +// if (m_px.isNull()) { +// Base::Console().Message("TRACE - QGCustomImage::load - pixmap no good\n"); +// } + prepareGeometryChange(); + setPixmap(m_px); + return(success); +} + +void QGCustomImage::paint ( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget) { + QStyleOptionGraphicsItem myOption(*option); + myOption.state &= ~QStyle::State_Selected; + + QGraphicsPixmapItem::paint (painter, &myOption, widget); +} diff --git a/src/Mod/TechDraw/Gui/QGCustomImage.h b/src/Mod/TechDraw/Gui/QGCustomImage.h new file mode 100644 index 000000000..535323bd8 --- /dev/null +++ b/src/Mod/TechDraw/Gui/QGCustomImage.h @@ -0,0 +1,63 @@ +/*************************************************************************** + * Copyright (c) 2016 WandererFan (wandererfan@gmail.com) * + * * + * 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 DRAWINGGUI_QGCUSTOMIMAGE_H +#define DRAWINGGUI_QGCUSTOMIMAGE_H + +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE +class QPainter; +class QStyleOptionGraphicsItem; +QT_END_NAMESPACE + +namespace TechDrawGui +{ + +class TechDrawGuiExport QGCustomImage : public QGraphicsPixmapItem +{ +public: + explicit QGCustomImage(void); + ~QGCustomImage(); + + enum {Type = QGraphicsItem::UserType + 201}; + int type() const override { return Type;} + + virtual void paint( QPainter *painter, + const QStyleOptionGraphicsItem *option, + QWidget *widget = nullptr ) override; + virtual void centerAt(QPointF centerPos); + virtual void centerAt(double cX, double cY); + virtual bool load(QString fileSpec); + +protected: + QPixmap m_px; + +}; + +} // namespace TechDrawGui + +#endif // DRAWINGGUI_QGCUSTOMIMAGE_H diff --git a/src/Mod/TechDraw/Gui/QGCustomSvg.cpp b/src/Mod/TechDraw/Gui/QGCustomSvg.cpp index 0469e68b4..aad1a8f63 100644 --- a/src/Mod/TechDraw/Gui/QGCustomSvg.cpp +++ b/src/Mod/TechDraw/Gui/QGCustomSvg.cpp @@ -51,22 +51,26 @@ QGCustomSvg::~QGCustomSvg() void QGCustomSvg::centerAt(QPointF centerPos) { - QRectF box = boundingRect(); - double width = box.width(); - double height = box.height(); - double newX = centerPos.x() - width/2.; - double newY = centerPos.y() - height/2.; - setPos(newX,newY); + if (group()) { + QRectF box = group()->boundingRect(); + double width = box.width(); + double height = box.height(); + double newX = centerPos.x() - width/2.; + double newY = centerPos.y() - height/2.; + setPos(newX,newY); + } } void QGCustomSvg::centerAt(double cX, double cY) { - QRectF box = boundingRect(); - double width = box.width(); - double height = box.height(); - double newX = cX - width/2.; - double newY = cY - height/2.; - setPos(newX,newY); + if (group()) { + QRectF box = group()->boundingRect(); + double width = box.width(); + double height = box.height(); + double newX = cX - width/2.; + double newY = cY - height/2.; + setPos(newX,newY); + } } bool QGCustomSvg::load(QByteArray *svgBytes) @@ -82,7 +86,7 @@ QRectF QGCustomSvg::boundingRect() const QRectF box = m_svgRender->viewBoxF(); double w = box.width(); double h = box.height(); - QRectF newRect(0,0,w*scale(),h*scale()); + QRectF newRect(0,0,w,h); return newRect.adjusted(-1.,-1.,1.,1.); } diff --git a/src/Mod/TechDraw/Gui/QGIUserTypes.h b/src/Mod/TechDraw/Gui/QGIUserTypes.h index 46333ed88..3203f9400 100644 --- a/src/Mod/TechDraw/Gui/QGIUserTypes.h +++ b/src/Mod/TechDraw/Gui/QGIUserTypes.h @@ -35,6 +35,8 @@ QGISectionLine: 172 QGIDecoration: 173 QGICenterLine: 174 QGICaption: 180 +QGIViewImage: 200 +QGCustomImage: 201 */ /* diff --git a/src/Mod/TechDraw/Gui/QGIView.cpp b/src/Mod/TechDraw/Gui/QGIView.cpp index eea359bd2..adf830064 100644 --- a/src/Mod/TechDraw/Gui/QGIView.cpp +++ b/src/Mod/TechDraw/Gui/QGIView.cpp @@ -403,6 +403,8 @@ void QGIView::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, Q QStyleOptionGraphicsItem myOption(*option); myOption.state &= ~QStyle::State_Selected; + //painter->drawRect(boundingRect()); + QGraphicsItemGroup::paint(painter, &myOption, widget); } diff --git a/src/Mod/TechDraw/Gui/QGIViewImage.cpp b/src/Mod/TechDraw/Gui/QGIViewImage.cpp new file mode 100644 index 000000000..d441fcfb2 --- /dev/null +++ b/src/Mod/TechDraw/Gui/QGIViewImage.cpp @@ -0,0 +1,144 @@ +/*************************************************************************** + * Copyright (c) 2016 WandererFan (wandererfan@gmail.com) * + * * + * 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 +#endif + +//#include + +#include +#include +#include +#include + +#include + +#include "QGCustomImage.h" +#include "QGCustomClip.h" +#include "QGIViewImage.h" + +using namespace TechDrawGui; + +QGIViewImage::QGIViewImage() +{ + setHandlesChildEvents(false); + setFlag(QGraphicsItem::ItemClipsChildrenToShape, false); + setCacheMode(QGraphicsItem::NoCache); + setAcceptHoverEvents(true); + setFlag(QGraphicsItem::ItemIsMovable, true); + setFlag(QGraphicsItem::ItemIsSelectable, true); + setFlag(QGraphicsItem::ItemSendsGeometryChanges, true); + + m_cliparea = new QGCustomClip(); + addToGroup(m_cliparea); + m_cliparea->setPos(0.,0.); + m_cliparea->setRect(0.,0.,5.,5.); + + m_imageItem = new QGCustomImage(); + m_cliparea->addToGroup(m_imageItem); + m_imageItem->setPos(0.,0.); +} + +QGIViewImage::~QGIViewImage() +{ + // m_imageItem belongs to this group and will be deleted by Qt +} + +QVariant QGIViewImage::itemChange(GraphicsItemChange change, const QVariant &value) +{ + + return QGIView::itemChange(change, value); +} + +void QGIViewImage::setViewImageFeature(TechDraw::DrawViewImage *obj) +{ + setViewFeature(static_cast(obj)); +} + +void QGIViewImage::updateView(bool update) +{ + auto viewImage( dynamic_cast(getViewObject()) ); + if( viewImage == nullptr ) { + return; + } + + if (update || + viewImage->isTouched() || + viewImage->Width.isTouched() || + viewImage->Height.isTouched() || + viewImage->ImageFile.isTouched()) { + draw(); + } + + if (viewImage->Scale.isTouched()) { + draw(); + } + + QGIView::updateView(update); +} + +void QGIViewImage::draw() +{ + if (!isVisible()) { + return; + } + + auto viewImage( dynamic_cast(getViewObject()) ); + QRectF newRect(0.0,0.0,viewImage->Width.getValue(),viewImage->Height.getValue()); + m_cliparea->setRect(newRect.adjusted(-1,-1,1,1)); + + drawImage(); + if (borderVisible) { + drawBorder(); + } +} + +void QGIViewImage::drawImage() +{ + auto viewImage( dynamic_cast(getViewObject()) ); + if( viewImage == nullptr ) { + return; + } + + if (!viewImage->ImageFile.isEmpty()) { + QString fileSpec = QString::fromUtf8(viewImage->ImageFile.getValue(),strlen(viewImage->ImageFile.getValue())); + m_imageItem->load(fileSpec); + m_imageItem->setScale(viewImage->Scale.getValue()); + QRectF br = m_cliparea->rect(); + double midX = br.width()/2.0; + double midY = br.height()/2.0; + m_imageItem->centerAt(midX,midY); + m_imageItem->show(); + } +} + + diff --git a/src/Mod/TechDraw/Gui/QGIViewImage.h b/src/Mod/TechDraw/Gui/QGIViewImage.h new file mode 100644 index 000000000..7ca5298f7 --- /dev/null +++ b/src/Mod/TechDraw/Gui/QGIViewImage.h @@ -0,0 +1,64 @@ +/*************************************************************************** + * Copyright (c) 2016 WandererFan (wandererfan@gmail.com) * + * * + * 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 DRAWINGGUI_QGRAPHICSITEMVIEWIMAGE_H +#define DRAWINGGUI_QGRAPHICSITEMVIEWIMAGE_H + +#include +#include +#include + +#include "QGIView.h" + +namespace TechDraw { +class DrawViewImage; +} + +namespace TechDrawGui +{ +class QGCustomImage; +class QGCustomClip; + +class TechDrawGuiExport QGIViewImage : public QGIView +{ +public: + QGIViewImage(); + ~QGIViewImage(); + + enum {Type = QGraphicsItem::UserType + 200}; + int type() const override { return Type;} + + virtual void updateView(bool update = false) override; + void setViewImageFeature(TechDraw::DrawViewImage *obj); + + virtual void draw() override; + +protected: + virtual void drawImage(); + QVariant itemChange(GraphicsItemChange change, const QVariant &value) override; + + QGCustomImage* m_imageItem; + QGCustomClip* m_cliparea; +}; + +} // namespace +#endif // DRAWINGGUI_QGRAPHICSITEMVIEWIMAGE_H diff --git a/src/Mod/TechDraw/Gui/QGIViewPart.cpp b/src/Mod/TechDraw/Gui/QGIViewPart.cpp index a4c952866..f1e62ebc1 100644 --- a/src/Mod/TechDraw/Gui/QGIViewPart.cpp +++ b/src/Mod/TechDraw/Gui/QGIViewPart.cpp @@ -250,7 +250,6 @@ void QGIViewPart::updateView(bool update) viewPart->isTouched() || viewPart->Source.isTouched() || viewPart->Direction.isTouched() || - viewPart->Tolerance.isTouched() || viewPart->Scale.isTouched() || viewPart->HardHidden.isTouched() || viewPart->SmoothVisible.isTouched() || @@ -290,6 +289,9 @@ void QGIViewPart::drawViewPart() if ( viewPart == nullptr ) { return; } + if (!viewPart->hasGeometry()) { + return; + } float lineWidth = viewPart->LineWidth.getValue() * lineScaleFactor; float lineWidthHid = viewPart->HiddenWidth.getValue() * lineScaleFactor; diff --git a/src/Mod/TechDraw/Gui/QGIViewSymbol.cpp b/src/Mod/TechDraw/Gui/QGIViewSymbol.cpp index 41698244e..7c7511bea 100644 --- a/src/Mod/TechDraw/Gui/QGIViewSymbol.cpp +++ b/src/Mod/TechDraw/Gui/QGIViewSymbol.cpp @@ -59,7 +59,7 @@ QGIViewSymbol::QGIViewSymbol() m_svgItem = new QGCustomSvg(); addToGroup(m_svgItem); - m_svgItem->setPos(0.,0.); + m_svgItem->centerAt(0.,0.); } QGIViewSymbol::~QGIViewSymbol() @@ -137,5 +137,5 @@ void QGIViewSymbol::symbolToSvg(QByteArray qba) if (!m_svgItem->load(&qba)) { Base::Console().Error("Error - Could not load Symbol into SVG renderer for %s\n", getViewObject()->getNameInDocument()); } - m_svgItem->setPos(0.,0.); + m_svgItem->centerAt(0.,0.); } diff --git a/src/Mod/TechDraw/Gui/QGVPage.cpp b/src/Mod/TechDraw/Gui/QGVPage.cpp index 3e6d8701c..c850f5abb 100644 --- a/src/Mod/TechDraw/Gui/QGVPage.cpp +++ b/src/Mod/TechDraw/Gui/QGVPage.cpp @@ -58,6 +58,7 @@ #include #include #include +#include #include "QGIDrawingTemplate.h" @@ -73,6 +74,7 @@ #include "QGIViewSymbol.h" #include "QGIViewClip.h" #include "QGIViewSpreadsheet.h" +#include "QGIViewImage.h" #include "QGIFace.h" #include "ZVALUE.h" @@ -287,6 +289,17 @@ QGIView * QGVPage::addDrawViewSpreadsheet(TechDraw::DrawViewSpreadsheet *view) return qview; } +QGIView * QGVPage::addDrawViewImage(TechDraw::DrawViewImage *view) +{ + QPoint qp(view->X.getValue(),view->Y.getValue()); + auto qview( new QGIViewImage ); + + qview->setViewFeature(view); + + addView(qview); + return qview; +} + QGIView * QGVPage::addViewDimension(TechDraw::DrawViewDimension *dim) { auto dimGroup( new QGIViewDimension ); diff --git a/src/Mod/TechDraw/Gui/QGVPage.h b/src/Mod/TechDraw/Gui/QGVPage.h index 9976bfd89..01f6b83ef 100644 --- a/src/Mod/TechDraw/Gui/QGVPage.h +++ b/src/Mod/TechDraw/Gui/QGVPage.h @@ -37,6 +37,7 @@ class DrawViewSymbol; class DrawViewClip; class DrawViewCollection; class DrawViewSpreadsheet; +class DrawViewImage; } namespace TechDrawGui @@ -69,6 +70,8 @@ public: QGIView * addDrawViewSymbol(TechDraw::DrawViewSymbol *view); QGIView * addDrawViewClip(TechDraw::DrawViewClip *view); QGIView * addDrawViewSpreadsheet(TechDraw::DrawViewSpreadsheet *view); + QGIView * addDrawViewImage(TechDraw::DrawViewImage *view); + QGIView * findView(App::DocumentObject *obj) const; QGIView * findParent(QGIView *) const; diff --git a/src/Mod/TechDraw/Gui/Resources/TechDraw.qrc b/src/Mod/TechDraw/Gui/Resources/TechDraw.qrc index 1087cc37b..90bd99318 100644 --- a/src/Mod/TechDraw/Gui/Resources/TechDraw.qrc +++ b/src/Mod/TechDraw/Gui/Resources/TechDraw.qrc @@ -9,6 +9,7 @@ icons/TechDraw_Tree_Spreadsheet.svg icons/TechDraw_Tree_Symbol.svg icons/TechDraw_Tree_View.svg + icons/TechDraw_Tree_Multi.svg icons/TechDraw_Pages.svg icons/TechDraw_ProjBottom.svg icons/TechDraw_ProjFront.svg @@ -32,6 +33,7 @@ icons/actions/techdraw-new-default.svg icons/actions/techdraw-new-pick.svg icons/actions/techdraw-view.svg + icons/actions/techdraw-multiview.svg icons/actions/techdraw-annotation.svg icons/actions/techdraw-clip.svg icons/actions/techdraw-clipplus.svg @@ -45,6 +47,7 @@ icons/actions/techdraw-toggleframe.svg icons/actions/techdraw-projgroup.svg icons/actions/techdraw-spreadsheet.svg + icons/actions/techdraw-image.svg icons/actions/section-up.svg icons/actions/section-down.svg icons/actions/section-left.svg diff --git a/src/Mod/TechDraw/Gui/Resources/icons/TechDraw_Tree_Multi.svg b/src/Mod/TechDraw/Gui/Resources/icons/TechDraw_Tree_Multi.svg new file mode 100644 index 000000000..e114a2518 --- /dev/null +++ b/src/Mod/TechDraw/Gui/Resources/icons/TechDraw_Tree_Multi.svg @@ -0,0 +1,57 @@ + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/src/Mod/TechDraw/Gui/Resources/icons/actions/techdraw-image.svg b/src/Mod/TechDraw/Gui/Resources/icons/actions/techdraw-image.svg new file mode 100644 index 000000000..276e9b7c6 --- /dev/null +++ b/src/Mod/TechDraw/Gui/Resources/icons/actions/techdraw-image.svg @@ -0,0 +1,481 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + Jakub Steiner + + + http://jimmac.musichall.cz + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Mod/TechDraw/Gui/Resources/icons/actions/techdraw-multiview.svg b/src/Mod/TechDraw/Gui/Resources/icons/actions/techdraw-multiview.svg new file mode 100644 index 000000000..81dd88f80 --- /dev/null +++ b/src/Mod/TechDraw/Gui/Resources/icons/actions/techdraw-multiview.svg @@ -0,0 +1,500 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + Jakub Steiner + + + http://jimmac.musichall.cz + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Mod/TechDraw/Gui/Resources/icons/actions/techdraw-viewsection.svg b/src/Mod/TechDraw/Gui/Resources/icons/actions/techdraw-viewsection.svg index fd32f65cd..b5fcefd4c 100644 --- a/src/Mod/TechDraw/Gui/Resources/icons/actions/techdraw-viewsection.svg +++ b/src/Mod/TechDraw/Gui/Resources/icons/actions/techdraw-viewsection.svg @@ -14,7 +14,7 @@ height="48.000000px" id="svg249" sodipodi:version="0.32" - inkscape:version="0.48.3.1 r9886" + inkscape:version="0.48.4 r9939" sodipodi:docname="techdraw-viewsection.svg" inkscape:export-filename="/home/jimmac/gfx/novell/pdes/trunk/docs/BIGmime-text.png" inkscape:export-xdpi="240.00000" @@ -361,36 +361,6 @@ fx="45.883327" fy="28.869568" r="19.467436" /> - - - image/svg+xml - + Jakub Steiner @@ -594,29 +564,30 @@ id="rect2221" width="31.612995" height="22.113316" - x="7.2478685" - y="15.429372" + x="7.6014218" + y="14.98743" rx="2.0176325" ry="1.7378116" /> + id="g4347" + style="fill:#d3d7cf;stroke:#888a85"> & subs, TechDraw::DrawPage* page) : +TaskLinkDim::TaskLinkDim(std::vector parts, std::vector& subs, TechDraw::DrawPage* page) : ui(new Ui_TaskLinkDim), - m_part(part), + m_parts(parts), m_subs(subs), m_page(page) { @@ -71,11 +71,16 @@ TaskLinkDim::TaskLinkDim(Part::Feature* part, std::vector& subs, Te loadAvailDims(); - ui->leFeature->setText(QString::fromStdString(part->getNameInDocument())); + ui->leFeature1->setText(QString::fromStdString(parts.at(0)->getNameInDocument())); ui->leGeometry1->setText(QString::fromStdString(subs.at(0))); if (subs.size() > 1) { ui->leGeometry2->setText(QString::fromStdString(subs.at(1))); + if (parts.at(0)->getNameInDocument() != parts.at(1)->getNameInDocument()) { + ui->leFeature2->setText(QString::fromStdString(parts.at(1)->getNameInDocument())); + } else { + ui->leFeature2->clear(); + } } } @@ -149,26 +154,37 @@ bool TaskLinkDim::dimReferencesSelection(const TechDraw::DrawViewDimension* dim) return result; } - Part::Feature* refPart = static_cast(dim->References3D.getValues().at(0)); + //Part::Feature* refPart = static_cast(dim->References3D.getValues().at(0)); + std::vector refParts; + std::vector docObjs = dim->References3D.getValues(); + for (auto& d: docObjs) { + Part::Feature* part = static_cast(d); + refParts.push_back(part); + } std::vector refSubs = dim->References3D.getSubValues(); - if (refPart == m_part) { - if (refSubs.size() == m_subs.size()) { - if (m_subs.size() == 0) { - //we're done. why did we get here? - } else if (refSubs.size() == 1) { - if (refSubs[0] == m_subs[0]) { - result = true; - } - } else { - if ( ((refSubs[0] == m_subs[0]) && - (refSubs[1] == m_subs[1])) || - ((refSubs[0] == m_subs[1]) && - (refSubs[1] == m_subs[0])) ) { - result = true; - } + if (refParts.size() == m_parts.size()) { + if(refParts.size() == 0) { + //shouldn't happen! + } else if (refParts.size() == 1) { + if ((refParts[0] == m_parts[0]) && + (refSubs[0] == m_subs[0]) ) { //everything matches + result = true; + } + } else if (refParts.size() == 2) { + if (( (refParts[0] == m_parts[0]) && + (refParts[1] == m_parts[1]) ) && + ( (refSubs[0] == m_subs[0]) && + (refSubs[1] == m_subs[1]) ) ) { + result = true; + } else if (( (refParts[0] == m_parts[1]) && + (refParts[1] == m_parts[0]) ) && + ( (refSubs[0] == m_subs[1]) && + (refSubs[1] == m_subs[0]) ) ) { + result = true; } } } + return result; } @@ -182,11 +198,11 @@ void TaskLinkDim::updateDims() QString name = child->data(0, Qt::UserRole).toString(); App::DocumentObject* obj = m_page->getDocument()->getObject(name.toStdString().c_str()); TechDraw::DrawViewDimension* dim = dynamic_cast(obj); - std::vector parts; - for (unsigned int iPart = 0; iPart < m_subs.size(); iPart++) { - parts.push_back(m_part); - } - dim->References3D.setValues(parts,m_subs); +// std::vector parts; +// for (unsigned int iPart = 0; iPart < m_subs.size(); iPart++) { +// parts.push_back(m_part); +// } + dim->References3D.setValues(m_parts,m_subs); std::string DimName = dim->getNameInDocument(); std::string measureType = "True"; Gui::Command::doCommand(Gui::Command::Gui,"App.activeDocument().%s.MeasureType = \'%s\'", @@ -204,8 +220,8 @@ void TaskLinkDim::updateDims() std::string DimName = dim->getNameInDocument(); Gui::Command::doCommand(Gui::Command::Gui,"App.activeDocument().%s.MeasureType = \'%s\'", DimName.c_str(),measureType.c_str()); - dim->References3D.setValue(0,""); //set this property to "empty" - //dim->MeasureType.setValue("Projected"); + dim->References3D.setValue(0,""); //DVD.References3D + dim->clear3DMeasurements(); //DVD.measurement.References3D } } } @@ -256,10 +272,10 @@ void TaskLinkDim::changeEvent(QEvent *e) ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -TaskDlgLinkDim::TaskDlgLinkDim(Part::Feature* part,std::vector& subs, TechDraw::DrawPage* page) : +TaskDlgLinkDim::TaskDlgLinkDim(std::vector parts,std::vector& subs, TechDraw::DrawPage* page) : TaskDialog() { - widget = new TaskLinkDim(part,subs,page); + widget = new TaskLinkDim(parts,subs,page); taskbox = new Gui::TaskView::TaskBox(Gui::BitmapFactory().pixmap("TechDraw_Dimension_Link"), widget->windowTitle(), true, 0); taskbox->groupLayout()->addWidget(widget); diff --git a/src/Mod/TechDraw/Gui/TaskLinkDim.h b/src/Mod/TechDraw/Gui/TaskLinkDim.h index 2a0504b5b..ea52a585f 100644 --- a/src/Mod/TechDraw/Gui/TaskLinkDim.h +++ b/src/Mod/TechDraw/Gui/TaskLinkDim.h @@ -45,7 +45,7 @@ class TaskLinkDim : public QWidget Q_OBJECT public: - TaskLinkDim(Part::Feature* part,std::vector& subs, TechDraw::DrawPage* page); + TaskLinkDim(std::vector parts,std::vector& subs, TechDraw::DrawPage* page); ~TaskLinkDim(); public: @@ -64,8 +64,8 @@ protected: private: Ui_TaskLinkDim * ui; - Part::Feature* m_part; - std::vector m_subs; + const std::vector m_parts; + const std::vector m_subs; TechDraw::DrawPage* m_page; }; @@ -74,7 +74,7 @@ class TaskDlgLinkDim : public Gui::TaskView::TaskDialog Q_OBJECT public: - TaskDlgLinkDim(Part::Feature* part,std::vector& subs, TechDraw::DrawPage* page); + TaskDlgLinkDim(std::vector parts,std::vector& subs, TechDraw::DrawPage* page); ~TaskDlgLinkDim(); public: diff --git a/src/Mod/TechDraw/Gui/TaskLinkDim.ui b/src/Mod/TechDraw/Gui/TaskLinkDim.ui index 4e8a445a5..d4b21d5a4 100644 --- a/src/Mod/TechDraw/Gui/TaskLinkDim.ui +++ b/src/Mod/TechDraw/Gui/TaskLinkDim.ui @@ -6,8 +6,8 @@ 0 0 - 342 - 430 + 400 + 472 @@ -61,7 +61,7 @@ - + Qt::NoFocus @@ -74,10 +74,43 @@ - + - Geometry: + Feature2: + + + + + + + Qt::NoFocus + + + color: rgb(120, 120, 120); + + + true + + + + + + + Qt::NoFocus + + + color: rgb(120, 120, 120); + + + true + + + + + + + Feature1: @@ -94,23 +127,17 @@ - - - - Qt::NoFocus - - - color: rgb(120, 120, 120); - - - true + + + + Geometry1: - - + + - Feature: + Geometry2: diff --git a/src/Mod/TechDraw/Gui/ViewProviderImage.cpp b/src/Mod/TechDraw/Gui/ViewProviderImage.cpp new file mode 100644 index 000000000..e3f997475 --- /dev/null +++ b/src/Mod/TechDraw/Gui/ViewProviderImage.cpp @@ -0,0 +1,87 @@ +/*************************************************************************** + * Copyright (c) 2016 WandererFan (wandererfan@gmail.com) * + * * + * 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 + +/// Here the FreeCAD includes sorted by Base,App,Gui...... +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ViewProviderImage.h" + +using namespace TechDrawGui; + +PROPERTY_SOURCE(TechDrawGui::ViewProviderImage, TechDrawGui::ViewProviderDrawingView) + +//************************************************************************** +// Construction/Destruction + +ViewProviderImage::ViewProviderImage() +{ + sPixmap = "actions/techdraw-image"; +} + +ViewProviderImage::~ViewProviderImage() +{ +} + +void ViewProviderImage::attach(App::DocumentObject *pcFeat) +{ + // call parent attach method + ViewProviderDrawingView::attach(pcFeat); +} + +void ViewProviderImage::setDisplayMode(const char* ModeName) +{ + ViewProviderDrawingView::setDisplayMode(ModeName); +} + +std::vector ViewProviderImage::getDisplayModes(void) const +{ + // get the modes of the father + std::vector StrList = ViewProviderDrawingView::getDisplayModes(); + + return StrList; +} + +void ViewProviderImage::updateData(const App::Property* prop) +{ + ViewProviderDrawingView::updateData(prop); +} + +TechDraw::DrawViewImage* ViewProviderImage::getViewObject() const +{ + return dynamic_cast(pcObject); +} + + diff --git a/src/Mod/TechDraw/Gui/ViewProviderImage.h b/src/Mod/TechDraw/Gui/ViewProviderImage.h new file mode 100644 index 000000000..b6ee285a5 --- /dev/null +++ b/src/Mod/TechDraw/Gui/ViewProviderImage.h @@ -0,0 +1,59 @@ +/*************************************************************************** + * Copyright (c) 2016 WandererFan (wandererfan@gmail.com) * + * * + * 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 DRAWINGGUI_VIEWPROVIDERIMAGE_H +#define DRAWINGGUI_VIEWPROVIDERIMAGE_H + +#include +#include +#include "ViewProviderDrawingView.h" + +namespace TechDrawGui { + + +class TechDrawGuiExport ViewProviderImage : public ViewProviderDrawingView +{ + PROPERTY_HEADER(TechDrawGui::ViewProviderImage); + +public: + /// constructor + ViewProviderImage(); + /// destructor + virtual ~ViewProviderImage(); + + + virtual void attach(App::DocumentObject *); + virtual void setDisplayMode(const char* ModeName); + virtual bool useNewSelectionModel(void) const {return false;} + /// returns a list of all possible modes + virtual std::vector getDisplayModes(void) const; + virtual void updateData(const App::Property*); + + virtual TechDraw::DrawViewImage* getViewObject() const; +}; + + +} // namespace TechDrawGui + + +#endif // DRAWINGGUI_VIEWPROVIDERIMAGE_H diff --git a/src/Mod/TechDraw/Gui/ViewProviderViewPart.cpp b/src/Mod/TechDraw/Gui/ViewProviderViewPart.cpp index 8c0a7b1e1..c510be33d 100644 --- a/src/Mod/TechDraw/Gui/ViewProviderViewPart.cpp +++ b/src/Mod/TechDraw/Gui/ViewProviderViewPart.cpp @@ -37,6 +37,7 @@ #include #include +#include #include #include @@ -87,6 +88,11 @@ void ViewProviderViewPart::onChanged(const App::Property* prop) void ViewProviderViewPart::attach(App::DocumentObject *pcFeat) { + TechDraw::DrawViewMulti* dvm = dynamic_cast(pcFeat); + if (dvm != nullptr) { + sPixmap = "TechDraw_Tree_Multi"; + } + // call parent attach method ViewProviderDocumentObject::attach(pcFeat); } diff --git a/src/Mod/TechDraw/Gui/Workbench.cpp b/src/Mod/TechDraw/Gui/Workbench.cpp index 0e8045500..66b64fd0c 100644 --- a/src/Mod/TechDraw/Gui/Workbench.cpp +++ b/src/Mod/TechDraw/Gui/Workbench.cpp @@ -63,6 +63,7 @@ Gui::MenuItem* Workbench::setupMenuBar() const *draw << "TechDraw_NewPageDef"; *draw << "TechDraw_NewPage"; *draw << "TechDraw_NewView"; + *draw << "TechDraw_NewMulti"; *draw << "TechDraw_ProjGroup"; *draw << "TechDraw_NewViewSection"; *draw << "TechDraw_Annotation"; @@ -75,6 +76,7 @@ Gui::MenuItem* Workbench::setupMenuBar() const *draw << "TechDraw_DraftView"; *draw << "TechDraw_ArchView"; *draw << "TechDraw_ExportPage"; + *draw << "TechDraw_Image"; //*draw << "TechDraw_Open"; //*part << "TechDraw_NewA3Landscape"; //*part << "TechDraw_OpenBrowserView"; @@ -96,6 +98,7 @@ Gui::ToolBarItem* Workbench::setupToolBars() const Gui::ToolBarItem *views = new Gui::ToolBarItem(root); views->setCommand("TechDraw Views"); *views << "TechDraw_NewView"; + *views << "TechDraw_NewMulti"; *views << "TechDraw_ProjGroup"; *views << "TechDraw_NewViewSection"; *views << "TechDraw_Annotation"; @@ -128,6 +131,7 @@ Gui::ToolBarItem* Workbench::setupToolBars() const Gui::ToolBarItem *decor = new Gui::ToolBarItem(root); decor->setCommand("TechDraw Decoration"); *decor << "TechDraw_NewHatch"; + *decor << "TechDraw_Image"; *decor << "TechDraw_ToggleFrame"; return root; } @@ -143,6 +147,7 @@ Gui::ToolBarItem* Workbench::setupCommandBars() const Gui::ToolBarItem *views = new Gui::ToolBarItem(root); views->setCommand("Views"); *views << "TechDraw_NewView"; + *views << "TechDraw_NewMulti"; *views << "TechDraw_ProjGroup"; *views << "TechDraw_NewViewSection"; *views << "TechDraw_Annotation"; @@ -174,6 +179,7 @@ Gui::ToolBarItem* Workbench::setupCommandBars() const Gui::ToolBarItem *decor = new Gui::ToolBarItem(root); decor->setCommand("TechDraw Decoration"); *decor << "TechDraw_NewHatch"; + *decor << "TechDraw_Image"; *decor << "TechDraw_ToggleFrame"; return root;