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