diff --git a/src/Gui/SoFCVectorizeSVGAction.cpp b/src/Gui/SoFCVectorizeSVGAction.cpp
index 893e0f2190..894c901f50 100644
--- a/src/Gui/SoFCVectorizeSVGAction.cpp
+++ b/src/Gui/SoFCVectorizeSVGAction.cpp
@@ -382,6 +382,7 @@ SoFCVectorizeSVGAction::SoFCVectorizeSVGAction() :
m_lineWidth(1.0),
m_usemm(false)
{
+ Base::Console().Message("SoFCVSA::SoFCVSA()\n");
SO_ACTION_CONSTRUCTOR(SoFCVectorizeSVGAction);
this->setOutput(new SoSVGVectorOutput);
this->p = new SoFCVectorizeSVGActionP(this);
@@ -400,6 +401,7 @@ SoFCVectorizeSVGAction::getSVGOutput(void) const
void SoFCVectorizeSVGAction::printHeader(void) const
{
+ Base::Console().Message("SoFCVSA::printHeader()\n");
std::ostream& str = this->getSVGOutput()->getFileStream();
str << "" << std::endl;
str << "" << std::endl;
@@ -433,6 +435,8 @@ void SoFCVectorizeSVGAction::printViewport(void) const
void SoFCVectorizeSVGAction::printBackground(void) const
{
+ Base::Console().Message("SoFCVSA::printBackground()\n");
+
SbVec2f mul = getRotatedViewportSize();
SbVec2f add = getRotatedViewportStartpos();
diff --git a/src/Mod/TechDraw/Gui/AppTechDrawGuiPy.cpp b/src/Mod/TechDraw/Gui/AppTechDrawGuiPy.cpp
index 48c9ff64ff..6e0063f3ef 100644
--- a/src/Mod/TechDraw/Gui/AppTechDrawGuiPy.cpp
+++ b/src/Mod/TechDraw/Gui/AppTechDrawGuiPy.cpp
@@ -38,8 +38,10 @@
#include
#include
+#include
#include
#include
+#include
#include
#include
#include
@@ -47,13 +49,11 @@
#include
#include
+#include
#include "MDIViewPage.h"
#include "ViewProviderPage.h"
-
-namespace TechDrawGui {
-//module level static C++ functions go here
-}
+#include "Grabber3d.h"
namespace TechDrawGui {
@@ -71,6 +71,9 @@ public:
add_varargs_method("exportPageAsSvg",&Module::exportPageAsSvg,
"exportPageAsSvg(DrawPageObject,FilePath) -- print page as Svg to file."
);
+ add_varargs_method("copyActiveViewToSvgFile",&Module::copyActiveViewToSvgFile,
+ "copyActiveViewToSvgFile(DrawPageObject,FilePath) -- copy ActiveView to Svg file."
+ );
initialize("This is a module for displaying drawings"); // register with Python
}
virtual ~Module() {}
@@ -237,7 +240,61 @@ private:
return Py::None();
}
+
+//!copyActiveViewToSvgFile(document, fileSpec)
+ Py::Object copyActiveViewToSvgFile(const Py::Tuple& args)
+ {
+ double result = 1.0;
+ PyObject *docObj = nullptr;
+ PyObject *colorObj = nullptr;
+ char* name;
+ App::Document* appDoc = nullptr;
+ std::string fileSpec;
+ double outWidth = 138.5; //TODO: change to A4 for release
+ double outHeight = 95.0; //ISO A5 defaults
+ bool paintBackground = true;
+ QColor bgColor = QColor(Qt::white);
+ double lineWidth = 1.0; //1 mm
+ double border = 0.0; //no border
+ int mode = 0; //SoRenderManager::RenderMode(0) - AS_IS
+
+ if (!PyArg_ParseTuple(args.ptr(), "Oet|ddpOddi",
+ &docObj, "utf-8",&name,
+ &outWidth, &outHeight,
+ &paintBackground, &colorObj,
+ &lineWidth, &border,
+ &mode)) {
+ throw Py::TypeError("expected (doc, file|,options)");
+ }
+
+ fileSpec = std::string(name);
+ PyMem_Free(name);
+
+ try {
+ if (PyObject_TypeCheck(docObj, &(App::DocumentPy::Type))) {
+ appDoc = static_cast(docObj)->getDocumentPtr();
+ if ( (colorObj != nullptr) &&
+ PyTuple_Check(colorObj)) {
+ App::Color c = TechDraw::DrawUtil::pyTupleToColor(colorObj);
+ bgColor = c.asValue();
+ }
+ result =
+ Grabber3d::copyActiveViewToSvgFile(appDoc, fileSpec,
+ outWidth, outHeight,
+ paintBackground, bgColor,
+ lineWidth, border,
+ mode); //TODO: add svg scale factor?
+ }
+ }
+ catch (Base::Exception &e) {
+ throw Py::Exception(Base::BaseExceptionFreeCADError, e.what());
+ }
+
+ PyObject* pyResult = nullptr;
+ pyResult = PyFloat_FromDouble(result);
+ return Py::asObject(pyResult);
+ }
};
PyObject* initModule()
diff --git a/src/Mod/TechDraw/Gui/CMakeLists.txt b/src/Mod/TechDraw/Gui/CMakeLists.txt
index bc6f126ef1..b0bbc28465 100644
--- a/src/Mod/TechDraw/Gui/CMakeLists.txt
+++ b/src/Mod/TechDraw/Gui/CMakeLists.txt
@@ -66,6 +66,7 @@ set(TechDrawGui_MOC_HDRS
TaskBalloon.h
QGIWeldSymbol.h
SymbolChooser.h
+ TaskActiveView.h
)
fc_wrap_cpp(TechDrawGui_MOC_SRCS ${TechDrawGui_MOC_HDRS})
@@ -96,6 +97,7 @@ set(TechDrawGui_UIC_SRCS
TaskRestoreLines.ui
TaskWeldingSymbol.ui
SymbolChooser.ui
+ TaskActiveView.ui
)
if(BUILD_QT5)
@@ -183,6 +185,11 @@ SET(TechDrawGui_SRCS
SymbolChooser.ui
SymbolChooser.cpp
SymbolChooser.h
+ TaskActiveView.ui
+ TaskActiveView.cpp
+ TaskActiveView.h
+ Grabber3d.cpp
+ Grabber3d.h
)
SET(TechDrawGuiView_SRCS
@@ -344,6 +351,7 @@ SET(TechDrawGuiTaskDlgs_SRCS
TaskCL2Lines.ui
TaskWeldingSymbol.ui
SymbolChooser.ui
+ TaskActiveView.ui
)
SOURCE_GROUP("TaskDialogs" FILES ${TechDrawGuiTaskDlgs_SRCS})
diff --git a/src/Mod/TechDraw/Gui/Command.cpp b/src/Mod/TechDraw/Gui/Command.cpp
index d3e28589fd..8e84578656 100644
--- a/src/Mod/TechDraw/Gui/Command.cpp
+++ b/src/Mod/TechDraw/Gui/Command.cpp
@@ -74,6 +74,7 @@
#include "MDIViewPage.h"
#include "TaskProjGroup.h"
#include "TaskSectionView.h"
+#include "TaskActiveView.h"
#include "ViewProviderPage.h"
using namespace TechDrawGui;
@@ -324,6 +325,40 @@ bool CmdTechDrawNewView::isActive(void)
return DrawGuiUtil::needPage(this);
}
+//===========================================================================
+// TechDraw_NewActiveView
+//===========================================================================
+
+DEF_STD_CMD_A(CmdTechDrawNewActiveView);
+
+CmdTechDrawNewActiveView::CmdTechDrawNewActiveView()
+ : Command("TechDraw_NewActiveView")
+{
+ sAppModule = "TechDraw";
+ sGroup = QT_TR_NOOP("TechDraw");
+ sMenuText = QT_TR_NOOP("Insert ActiveView(3D) as View in Page");
+ sToolTipText = sMenuText;
+ sWhatsThis = "TechDraw_NewActiveView";
+ sStatusTip = sToolTipText;
+ sPixmap = "actions/techdraw-activeview";
+}
+
+void CmdTechDrawNewActiveView::activated(int iMsg)
+{
+ Q_UNUSED(iMsg);
+ TechDraw::DrawPage* page = DrawGuiUtil::findPage(this);
+ if (!page) {
+ return;
+ }
+ std::string PageName = page->getNameInDocument();
+ Gui::Control().showDialog(new TaskDlgActiveView(page));
+}
+
+bool CmdTechDrawNewActiveView::isActive(void)
+{
+ return DrawGuiUtil::needPage(this);
+}
+
//===========================================================================
// TechDraw_NewViewSection
//===========================================================================
@@ -1222,6 +1257,7 @@ void CreateTechDrawCommands(void)
rcCmdMgr.addCommand(new CmdTechDrawNewPageDef());
rcCmdMgr.addCommand(new CmdTechDrawNewPage());
rcCmdMgr.addCommand(new CmdTechDrawNewView());
+ rcCmdMgr.addCommand(new CmdTechDrawNewActiveView());
rcCmdMgr.addCommand(new CmdTechDrawNewViewSection());
rcCmdMgr.addCommand(new CmdTechDrawNewViewDetail());
// rcCmdMgr.addCommand(new CmdTechDrawNewMulti()); //deprecated
diff --git a/src/Mod/TechDraw/Gui/Grabber3d.cpp b/src/Mod/TechDraw/Gui/Grabber3d.cpp
new file mode 100644
index 0000000000..dcb6a31a2b
--- /dev/null
+++ b/src/Mod/TechDraw/Gui/Grabber3d.cpp
@@ -0,0 +1,384 @@
+/***************************************************************************
+ * Copyright (c) 2019 WandererFan *
+ * *
+ * This file is part of the FreeCAD CAx development system. *
+ * *
+ * This library is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Library General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 2 of the License, or (at your option) any later version. *
+ * *
+ * This library is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU Library General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Library General Public *
+ * License along with this library; see the file COPYING.LIB. If not, *
+ * write to the Free Software Foundation, Inc., 59 Temple Place, *
+ * Suite 330, Boston, MA 02111-1307, USA *
+ * *
+ ***************************************************************************/
+
+#include "PreCompiled.h"
+
+#ifndef _PreComp_
+
+#endif
+#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
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "Rez.h"
+#include "QGVPage.h"
+#include "MDIViewPage.h"
+#include "DrawGuiUtil.h"
+
+#include "Grabber3d.h"
+
+using namespace TechDrawGui;
+using namespace TechDraw;
+using namespace Gui;
+
+ //notes for selection view
+ //SoSeparator* newSG;
+ //for obj in objList:
+ // vProv = obj.ViewObject
+ // sg = vProv.getSG(obj);
+ // for child in sg:
+ // newSG->addChild();
+ //
+
+//creates Svg file and returns estimate of scale
+double Grabber3d::copyActiveViewToSvgFile(App::Document* appDoc,
+ std::string fileSpec,
+ double outWidth, double outHeight,
+ bool paintBackground, const QColor& bgColor,
+ double lineWidth, double border,
+ int renderMode)
+{
+// Base::Console().Message("G3d::copyActiveViewToSvgFile()\n");
+ double result = 1.0; //best estimate of scale of result
+
+ //get the active view
+ Gui::Document* guiDoc = Gui::Application::Instance->getDocument(appDoc);
+ Gui::MDIView* mdiView = guiDoc->getActiveView();
+ if (mdiView == nullptr) {
+ Base::Console().Warning("G3d::copyActiveViewToSvgFile - no ActiveView - returning\n");
+ return result;
+ }
+
+ View3DInventor* view3d = qobject_cast(mdiView);
+ if (view3d == nullptr) {
+ Base::Console().Warning("G3d::copyActiveViewToSvgFile - no viewer for ActiveView - returning\n");
+ return result;
+ }
+
+ View3DInventorViewer* viewer = view3d->getViewer();
+ if (viewer == nullptr) {
+ Base::Console().Warning("G3d::copyActiveViewToSvgFile - could not create viewer - returning\n");
+ return result;
+ }
+
+ //save parameters of source view
+ double mdiWidth = view3d->width();
+ double mdiHigh = view3d->height();
+
+ SbViewportRegion sourceVPRegion = viewer->getSoRenderManager()->getViewportRegion();
+ SoCamera* sourceCam = viewer->getSoRenderManager()->getCamera();
+ SbRotation sourceOrient = viewer->getCameraOrientation();
+ SbVec3f sourcePos = viewer->getSoRenderManager()->getCamera()->position.getValue();
+ double sourceNear = viewer->getSoRenderManager()->getCamera()->nearDistance.getValue();
+ double sourceFar = viewer->getSoRenderManager()->getCamera()->farDistance.getValue();
+ double sourceFocal = viewer->getSoRenderManager()->getCamera()->focalDistance.getValue();
+ double sourceAspect = viewer->getSoRenderManager()->getCamera()->aspectRatio.getValue();
+ SoOrthographicCamera* oCam = nullptr;
+ SoPerspectiveCamera* pCam = nullptr;
+ double sourceHeight = 0.0;
+ double sourceAngle = 45.0;
+ if (sourceCam->getTypeId() == SoOrthographicCamera::getClassTypeId()) {
+ oCam = dynamic_cast(sourceCam);
+ sourceHeight = oCam->height.getValue();
+ } else if (sourceCam->getTypeId() == SoPerspectiveCamera::getClassTypeId()) {
+ pCam = dynamic_cast(sourceCam);
+ sourceAngle = pCam->heightAngle.getValue();
+ }
+ oCam = nullptr;
+ pCam = nullptr;
+
+ //make a view for rendering Svg
+ View3DInventor* view3DI = new View3DInventor(0, 0); //essentially an undisplayed mdi
+// view3DI->setWindowTitle(QString::fromUtf8("SvgRenderViewer")); //fluff
+// Gui::getMainWindow()->addWindow(view3DI); //just for debugging. comment for release.
+
+ View3DInventorViewer* viewerSvg = view3DI->getViewer();
+ viewerSvg->setBackgroundColor(QColor(Qt::white));
+
+ SoRenderManager* renderMgr = viewerSvg->getSoRenderManager();
+ renderMgr->setRenderMode(SoRenderManager::RenderMode(renderMode));
+
+ SbViewportRegion targetVPRegion;
+ targetVPRegion.setWindowSize(mdiWidth, mdiHigh);
+ targetVPRegion.setPixelsPerInch(sourceVPRegion.getPixelsPerInch());
+ renderMgr->setViewportRegion(targetVPRegion);
+
+ auto sgOld = viewer->getSceneGraph();
+ SoSeparator* sgNew = copySceneGraph(sgOld);
+ viewerSvg->setSceneGraph(sgNew);
+
+ if (sourceCam->getTypeId() == SoOrthographicCamera::getClassTypeId()) {
+ viewerSvg->setCameraType(SoOrthographicCamera::getClassTypeId());
+ } else if (sourceCam->getTypeId() == SoPerspectiveCamera::getClassTypeId()) {
+ viewerSvg->setCameraType(SoPerspectiveCamera::getClassTypeId());
+ }
+
+// SoWriteAction writeAction; //dump the IV (debugging)
+// writeAction.apply(sgNew);
+
+ //set Svg view params to match source
+ SoCamera* svgCam = viewerSvg->getSoRenderManager()->getCamera();
+ double zoomFactor = 1.0; //not used
+ svgCam->orientation.setValue(sourceOrient);
+ svgCam->position.setValue(sourcePos);
+ svgCam->nearDistance.setValue(sourceNear);
+ svgCam->farDistance.setValue(sourceFar);
+ svgCam->focalDistance.setValue(sourceFocal);
+ svgCam->aspectRatio.setValue(sourceAspect);
+ if (svgCam->getTypeId() == SoOrthographicCamera::getClassTypeId()) {
+ SoOrthographicCamera* oSvgCam = dynamic_cast(svgCam);
+ double newHeight = sourceHeight * zoomFactor;
+ oSvgCam->height.setValue(newHeight);
+ } else if (svgCam->getTypeId() == SoPerspectiveCamera::getClassTypeId()) {
+ SoPerspectiveCamera* vSvgCam = dynamic_cast(svgCam);
+ vSvgCam->heightAngle.setValue(sourceAngle);
+ }
+
+ viewerSvg->redraw();
+
+ std::unique_ptr va;
+ va = std::unique_ptr(new SoFCVectorizeSVGAction());
+
+ SoVectorOutput* out = va->getOutput();
+ if (!out || !out->openFile(fileSpec.c_str())) {
+ Base::Console().Error("G3D::copyActiveViewToSvgFile - can not open file - %s/n", fileSpec.c_str());
+ return result;
+ }
+ QColor dbColor(Qt::blue);
+ execVectorizeAction(viewerSvg,
+ va.get(),
+ outWidth, outHeight,
+ paintBackground, bgColor,
+ lineWidth, border);
+
+ out->closeFile();
+
+ result = getViewerScale(viewerSvg); //screen : world
+
+ double pScale = getPaperScale(viewerSvg, outWidth, outHeight);
+
+ //TODO: figure out net scaling world -> screen -> paper
+ Base::Console().Log(
+ "G3d::copyActiveViewToSvgFile - approx screen:world scale: 1:%.5f w/ort pixel size issues\n",
+ result);
+ Base::Console().Log(
+ "G3d::copyActiveViewToSvgFile - approx paper/screen scale: 1:%.5f w/ort pixel size issues\n",
+ pScale);
+
+// postProcessSvg(fileSpec);
+
+ view3DI->close(); //comment out for debugging
+
+ viewerSvg->setSceneGraph(nullptr);
+ sgNew->unref();
+ sgNew = nullptr;
+
+ return result;
+}
+
+//==============================================================================
+
+SoSeparator* Grabber3d::copySceneGraph(SoNode* sgIn)
+{
+// Base::Console().Message("G3d::copySceneGraph()\n");
+ SoSeparator* result = new SoSeparator();
+
+ SoDirectionalLight* newLight = new SoDirectionalLight;
+ result->addChild(newLight);
+
+ SoNodeList* sgChildren = sgIn->getChildren();
+ int childSize = sgChildren->getLength();
+
+ //gather up the nodes to display
+ for (int i=0; i < childSize; i++) {
+ SoNode* c = (*sgChildren)[i];
+ if (c->isOfType(SoGroup::getClassTypeId())) {
+ auto cCopy = c->copy();
+ result->addChild(cCopy);
+ }
+ }
+
+ result->ref();
+ return result;
+}
+
+//==============================================================================
+
+//loosely based on View3DInventorViewer::saveGraphic
+void Grabber3d::execVectorizeAction(Gui::View3DInventorViewer* viewer,
+ SoVectorizeAction* va,
+ double width, double height,
+ bool paintBackground, const QColor& bgColor,
+ double lineWidth, double border)
+{
+// Base::Console().Message("G3d::execVectorizeAction() - va: %X\n", va);
+ if (va->getTypeId() == SoFCVectorizeSVGAction::getClassTypeId()) {
+ SoFCVectorizeSVGAction* vaFC = static_cast(va);
+ vaFC->setBackgroundState(paintBackground);
+ vaFC->setLineWidth(lineWidth);
+ vaFC->setUseMM(true);
+ }
+
+ if (paintBackground && bgColor.isValid()) {
+ va->setBackgroundColor(true, SbColor(bgColor.redF(), bgColor.greenF(), bgColor.blueF()));
+ } else {
+ va->setBackgroundColor(false);
+ }
+ va->setOrientation(SoVectorizeAction::PORTRAIT); //don't play with my w x h
+
+ va->beginPage(SbVec2f(border, border), SbVec2f(width, height));
+ va->beginViewport();
+ va->calibrate(viewer->getSoRenderManager()->getViewportRegion());
+ va->apply(viewer->getSoRenderManager()->getSceneGraph());
+ va->endViewport();
+ va->endPage();
+}
+
+//==============================================================================
+//find scale factor screen:world
+double Grabber3d::getViewerScale(Gui::View3DInventorViewer* viewer)
+{
+// Base::Console().Message("G3d::getViewerScale()\n");
+
+ double result = 1;
+// double printerpxmm = 3.94; //? 100 dpi?
+ double coinpxmm = 2.83; //72 dpi
+// QScreen *screen = QGuiApplication::primaryScreen();
+// double qtppi = screen->physicalDotsPerInch(); //~111 dpi
+// double qtpxmm = qtppi / 25.4;
+
+ SbViewportRegion vpRegion = viewer->getSoRenderManager()->getViewportRegion();
+ SbVec2s winSizePx = vpRegion.getWindowSize(); //pixel coords
+
+ Base::Vector3d p1v(0,0,0);
+ Base::Vector3d p2v(winSizePx[0] - 1, winSizePx[1] - 1);
+ double screenLengthpx = (p2v - p1v).Length(); //length in pixels
+ double screenLengthmm = (screenLengthpx / coinpxmm);
+
+ SbVec2s p1s(0,0);
+ SbVec2s p2s(winSizePx[0] - 1, winSizePx[1] - 1);
+ SbVec3f p1w = viewer->getPointOnScreen(p1s);
+ SbVec3f p2w = viewer->getPointOnScreen(p2s);
+ double worldLengthmm = (p2w - p1w).length(); //mm
+
+ result = worldLengthmm / screenLengthmm;
+ return result;
+}
+//==============================================================================
+
+//find scale factor screen:"paper"
+double Grabber3d::getPaperScale(Gui::View3DInventorViewer* viewer,
+ double pWidth, double pHeight)
+{
+// Base::Console().Message("G3d::getPaperScale()\n");
+
+ double result = 1;
+// double printerpxmm = 3.94; //? 100 dpi?
+ double coinpxmm = 2.83; //72 dpi
+// QScreen *screen = QGuiApplication::primaryScreen();
+// double qtppi = screen->physicalDotsPerInch(); //~111 dpi
+// double qtpxmm = qtppi / 25.4;
+ SbViewportRegion vpRegion = viewer->getSoRenderManager()->getViewportRegion();
+ SbVec2s winSizePx = vpRegion.getWindowSize(); //pixel coords
+
+ Base::Vector3d p1v(0,0,0);
+ Base::Vector3d p2v(winSizePx[0] - 1, winSizePx[1] - 1);
+ double screenLengthpx = (p2v - p1v).Length(); //length in pixels
+
+// double screenLengthmm = (screenLengthpx / qtpxmm);
+ double screenLengthmm = (screenLengthpx / coinpxmm);
+
+ double paperLengthmm = sqrt( pow(pWidth, 2) + pow(pHeight, 2));
+
+ result = paperLengthmm / screenLengthmm;
+
+ double paperLengthpx = sqrt( pow(pWidth*coinpxmm, 2) + pow(pHeight*coinpxmm, 2));
+ double resultpx = paperLengthpx / screenLengthpx;
+ Base::Console().Log("G3d::getPaperScale - screenLenpx: %.3f paperLenpx: %.3f resultpx: %.3f\n",
+ screenLengthpx, paperLengthpx, resultpx);
+
+ Base::Console().Log("G3d::getPaperScale - screenLen: %.3f paperLen: %.3f result: %.3f\n",
+ screenLengthmm, paperLengthmm, result);
+ return result;
+}
+
+//==============================================================================
+
+void Grabber3d::postProcessSvg(std::string fileSpec)
+{
+ (void) fileSpec;
+}
diff --git a/src/Mod/TechDraw/Gui/Grabber3d.h b/src/Mod/TechDraw/Gui/Grabber3d.h
new file mode 100644
index 0000000000..a2a4e2d560
--- /dev/null
+++ b/src/Mod/TechDraw/Gui/Grabber3d.h
@@ -0,0 +1,82 @@
+/***************************************************************************
+ * Copyright (c) 2019 WandererFan *
+ * *
+ * This file is part of the FreeCAD CAx development system. *
+ * *
+ * This library is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Library General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 2 of the License, or (at your option) any later version. *
+ * *
+ * This library is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU Library General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Library General Public *
+ * License along with this library; see the file COPYING.LIB. If not, *
+ * write to the Free Software Foundation, Inc., 59 Temple Place, *
+ * Suite 330, Boston, MA 02111-1307, USA *
+ * *
+ ***************************************************************************/
+
+#ifndef _Grabber3d_h_
+#define _Grabber3d_h_
+
+
+class SoSeparator;
+class SoCamera;
+class SoNode;
+class SbVec2s;
+class SbVec2f;
+class SbVec2d;
+class SoVectorizeAction;
+
+namespace App {
+class Document;
+class DocumentObject;
+class NavigationStyle;
+}
+namespace Gui {
+class Document;
+class View3DInventorViewer;
+}
+
+#include "MDIViewPage.h"
+
+namespace TechDraw {
+}
+
+namespace TechDrawGui
+{
+
+/// Utility functions for obtaining 3d window image
+class TechDrawGuiExport Grabber3d {
+ public:
+ static double copyActiveViewToSvgFile(App::Document* appDoc,
+ std::string fileSpec,
+ double outWidth = 138.5, //TODO: change to A4 for release
+ double outHeight = 95.0, //ISO A5 defaults
+ bool paintBackground = true,
+ const QColor& bgcolor = QColor(Qt::white),
+ double lineWidth = 1.0, //1 mm
+ double border = 0.0, //no border
+ int mode = 0); //SoRenderManager::RenderMode(0) - AS_IS
+
+ static SoSeparator* copySceneGraph(SoNode* sgIn);
+
+ static void execVectorizeAction(Gui::View3DInventorViewer* viewer,
+ SoVectorizeAction* va,
+ double width, double height,
+ bool paintBackground, const QColor& bgcolor,
+ double lineWidth, double border);
+
+ static double getViewerScale(Gui::View3DInventorViewer* viewer);
+ static double getPaperScale(Gui::View3DInventorViewer* viewer,
+ double pWidth, double pHeight);
+
+ static void postProcessSvg(std::string fileSpec);
+};
+
+} //end namespace TechDrawGui
+#endif
diff --git a/src/Mod/TechDraw/Gui/Resources/TechDraw.qrc b/src/Mod/TechDraw/Gui/Resources/TechDraw.qrc
index 0c0c5060e1..4891276c9d 100644
--- a/src/Mod/TechDraw/Gui/Resources/TechDraw.qrc
+++ b/src/Mod/TechDraw/Gui/Resources/TechDraw.qrc
@@ -43,6 +43,7 @@
icons/actions/techdraw-new-default.svg
icons/actions/techdraw-new-pick.svg
icons/actions/techdraw-view.svg
+ icons/actions/techdraw-activeview.svg
icons/actions/techdraw-multiview.svg
icons/actions/techdraw-annotation.svg
icons/actions/techdraw-clip.svg
diff --git a/src/Mod/TechDraw/Gui/Resources/icons/actions/techdraw-activeview.svg b/src/Mod/TechDraw/Gui/Resources/icons/actions/techdraw-activeview.svg
new file mode 100644
index 0000000000..5b814cc300
--- /dev/null
+++ b/src/Mod/TechDraw/Gui/Resources/icons/actions/techdraw-activeview.svg
@@ -0,0 +1,130 @@
+
+
diff --git a/src/Mod/TechDraw/Gui/TaskActiveView.cpp b/src/Mod/TechDraw/Gui/TaskActiveView.cpp
new file mode 100644
index 0000000000..0461e2dfa9
--- /dev/null
+++ b/src/Mod/TechDraw/Gui/TaskActiveView.cpp
@@ -0,0 +1,259 @@
+/***************************************************************************
+ * Copyright (c) 2019 Wandererfan
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+#include
+
+#include "DrawGuiStd.h"
+#include "QGVPage.h"
+#include "QGIView.h"
+#include "Grabber3d.h"
+#include "Rez.h"
+
+#include "TaskActiveView.h"
+
+using namespace Gui;
+using namespace TechDraw;
+using namespace TechDrawGui;
+
+//ctor for creation
+TaskActiveView::TaskActiveView(TechDraw::DrawPage* pageFeat) :
+ ui(new Ui_TaskActiveView),
+ m_pageFeat(pageFeat),
+ m_symbolFeat(nullptr)
+{
+// Base::Console().Message("TAV::TAV() - create mode\n");
+ if (m_pageFeat == nullptr) {
+ //should be caught in CMD caller
+ Base::Console().Error("TaskActiveView - bad parameters. Can not proceed.\n");
+ return;
+ }
+ ui->setupUi(this);
+
+ setUiPrimary();
+}
+
+TaskActiveView::~TaskActiveView()
+{
+ delete ui;
+}
+
+void TaskActiveView::updateTask()
+{
+// blockUpdate = true;
+
+// blockUpdate = false;
+}
+
+void TaskActiveView::changeEvent(QEvent *e)
+{
+ if (e->type() == QEvent::LanguageChange) {
+ ui->retranslateUi(this);
+ }
+}
+
+void TaskActiveView::setUiPrimary()
+{
+// Base::Console().Message("TAV::setUiPrimary()\n");
+ setWindowTitle(QObject::tr("ActiveView to TD View"));
+}
+
+void TaskActiveView::blockButtons(bool b)
+{
+ Q_UNUSED(b);
+}
+
+//******************************************************************************
+TechDraw::DrawViewSymbol* TaskActiveView::createActiveView(void)
+{
+// Base::Console().Message("TAV::createActiveView()\n");
+
+ std::string symbolName = m_pageFeat->getDocument()->getUniqueObjectName("DrawActiveView");
+ std::string symbolType = "TechDraw::DrawViewSymbol";
+
+ std::string pageName = m_pageFeat->getNameInDocument();
+
+ Command::doCommand(Command::Doc,"App.activeDocument().addObject('%s','%s')",
+ symbolType.c_str(),symbolName.c_str());
+ Command::doCommand(Command::Doc,"App.activeDocument().%s.addView(App.activeDocument().%s)",
+ pageName.c_str(), symbolName.c_str());
+
+ App::Document* appDoc = m_pageFeat->getDocument();
+ QTemporaryFile tempFile;
+ if (!tempFile.open()) { //open() creates temp file
+ Base::Console().Error("TAV::createActiveView - could not open temp file\n");
+ return nullptr;
+ }
+ tempFile.close();
+
+ std::string fileSpec = Base::Tools::toStdString(tempFile.fileName());
+
+ //double estScale =
+ Grabber3d::copyActiveViewToSvgFile(appDoc, fileSpec,
+ ui->qsbWidth->rawValue(),
+ ui->qsbHeight->rawValue(),
+ ui->cbbg->isChecked(),
+ ui->ccBgColor->color(),
+ ui->qsbWeight->rawValue(),
+ ui->qsbBorder->rawValue(),
+ ui->cbMode->currentIndex());
+#if PY_MAJOR_VERSION < 3
+ Command::doCommand(Command::Doc,"f = open(unicode(\"%s\",'utf-8'),'r')",(const char*)fileSpec.c_str());
+#else
+ Command::doCommand(Command::Doc,"f = open(\"%s\",'r')",(const char*)fileSpec.c_str());
+#endif
+ Command::doCommand(Command::Doc,"svg = f.read()");
+// Command::doCommand(Command::Doc,"print('length of svg: {}'.format(len(svg)))");
+
+ Command::doCommand(Command::Doc,"f.close()");
+ Command::doCommand(Command::Doc,"App.activeDocument().%s.Symbol = svg",symbolName.c_str());
+
+ App::DocumentObject* newObj = m_pageFeat->getDocument()->getObject(symbolName.c_str());
+ TechDraw::DrawViewSymbol* newSym = dynamic_cast(newObj);
+ if ( (newObj == nullptr) ||
+ (newSym == nullptr) ) {
+ throw Base::RuntimeError("TaskActiveView - new symbol object not found");
+ }
+
+ return newSym;
+}
+
+//******************************************************************************
+
+void TaskActiveView::saveButtons(QPushButton* btnOK,
+ QPushButton* btnCancel)
+{
+ m_btnOK = btnOK;
+ m_btnCancel = btnCancel;
+}
+
+void TaskActiveView::enableTaskButtons(bool b)
+{
+ m_btnOK->setEnabled(b);
+ m_btnCancel->setEnabled(b);
+}
+
+//******************************************************************************
+
+bool TaskActiveView::accept()
+{
+// Base::Console().Message("TAV::accept()\n");
+ Gui::Command::openCommand("Create ActiveView");
+ m_symbolFeat = createActiveView();
+// m_symbolFeat->requestPaint();
+ m_symbolFeat->recomputeFeature();
+ Gui::Command::updateActive();
+ Gui::Command::commitCommand();
+
+ Gui::Command::doCommand(Gui::Command::Gui,"Gui.ActiveDocument.resetEdit()");
+
+ return true;
+}
+
+bool TaskActiveView::reject()
+{
+// Base::Console().Message("TAV::reject()\n");
+ //nothing to remove.
+
+ Gui::Command::doCommand(Gui::Command::Gui,"App.activeDocument().recompute()");
+ Gui::Command::doCommand(Gui::Command::Gui,"Gui.ActiveDocument.resetEdit()");
+
+ return false;
+}
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+TaskDlgActiveView::TaskDlgActiveView(TechDraw::DrawPage* page)
+ : TaskDialog()
+{
+ widget = new TaskActiveView(page);
+ taskbox = new Gui::TaskView::TaskBox(Gui::BitmapFactory().pixmap("actions/techdraw-activeview"),
+ widget->windowTitle(), true, 0);
+ taskbox->groupLayout()->addWidget(widget);
+ Content.push_back(taskbox);
+}
+
+TaskDlgActiveView::~TaskDlgActiveView()
+{
+}
+
+void TaskDlgActiveView::update()
+{
+// widget->updateTask();
+}
+
+void TaskDlgActiveView::modifyStandardButtons(QDialogButtonBox* box)
+{
+ QPushButton* btnOK = box->button(QDialogButtonBox::Ok);
+ QPushButton* btnCancel = box->button(QDialogButtonBox::Cancel);
+ widget->saveButtons(btnOK, btnCancel);
+}
+
+//==== calls from the TaskView ===============================================================
+void TaskDlgActiveView::open()
+{
+}
+
+void TaskDlgActiveView::clicked(int)
+{
+}
+
+bool TaskDlgActiveView::accept()
+{
+ widget->accept();
+ return true;
+}
+
+bool TaskDlgActiveView::reject()
+{
+ widget->reject();
+ return true;
+}
+
+#include
diff --git a/src/Mod/TechDraw/Gui/TaskActiveView.h b/src/Mod/TechDraw/Gui/TaskActiveView.h
new file mode 100644
index 0000000000..508b9add1d
--- /dev/null
+++ b/src/Mod/TechDraw/Gui/TaskActiveView.h
@@ -0,0 +1,129 @@
+/***************************************************************************
+ * Copyright (c) 2019 WandererFan *
+ * *
+ * This file is part of the FreeCAD CAx development system. *
+ * *
+ * This library is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Library General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 2 of the License, or (at your option) any later version. *
+ * *
+ * This library is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU Library General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Library General Public *
+ * License along with this library; see the file COPYING.LIB. If not, *
+ * write to the Free Software Foundation, Inc., 59 Temple Place, *
+ * Suite 330, Boston, MA 02111-1307, USA *
+ * *
+ ***************************************************************************/
+
+#ifndef TECHDRAWGUI_TASKWELDINGSYMBOL_H
+#define TECHDRAWGUI_TASKWELDINGSYMBOL_H
+
+#include
+
+#include
+#include
+#include
+#include
+
+#include
+
+class Ui_TaskActiveView;
+
+namespace App {
+class DocumentObject;
+}
+
+namespace TechDraw
+{
+class DrawPage;
+class DrawView;
+class DrawViewSymbol;
+}
+
+namespace TechDrawGui
+{
+class QGVPage;
+class QGIView;
+class MDIViewPage;
+
+class TechDrawGuiExport TaskActiveView : public QWidget
+{
+ Q_OBJECT
+
+public:
+ TaskActiveView(TechDraw::DrawPage* pageFeat);
+ ~TaskActiveView();
+
+public Q_SLOTS:
+
+public:
+ virtual bool accept();
+ virtual bool reject();
+ void updateTask();
+ void saveButtons(QPushButton* btnOK,
+ QPushButton* btnCancel);
+ void enableTaskButtons(bool b);
+
+protected Q_SLOTS:
+
+protected:
+ void changeEvent(QEvent *e);
+
+ void blockButtons(bool b);
+ void setUiPrimary(void);
+
+ TechDraw::DrawViewSymbol* createActiveView(void);
+
+private:
+ Ui_TaskActiveView* ui;
+
+ TechDraw::DrawPage* m_pageFeat;
+ TechDraw::DrawViewSymbol* m_symbolFeat;
+
+ QPushButton* m_btnOK;
+ QPushButton* m_btnCancel;
+
+};
+
+
+class TaskDlgActiveView : public Gui::TaskView::TaskDialog
+{
+ Q_OBJECT
+
+public:
+ TaskDlgActiveView(TechDraw::DrawPage* pageFeat);
+ ~TaskDlgActiveView();
+
+public:
+ /// is called the TaskView when the dialog is opened
+ virtual void open();
+ /// is called by the framework if an button is clicked which has no accept or reject role
+ virtual void clicked(int);
+ /// is called by the framework if the dialog is accepted (Ok)
+ virtual bool accept();
+ /// is called by the framework if the dialog is rejected (Cancel)
+ virtual bool reject();
+ /// is called by the framework if the user presses the help button
+ virtual void helpRequested() { return;}
+ virtual bool isAllowedAlterDocument(void) const
+ { return false; }
+ void update();
+
+ void modifyStandardButtons(QDialogButtonBox* box);
+
+protected:
+
+private:
+ TaskActiveView* widget;
+ Gui::TaskView::TaskBox* taskbox;
+
+};
+
+} //namespace TechDrawGui
+
+#endif // #ifndef TECHDRAWGUI_TASKWELDINGSYMBOL_H
diff --git a/src/Mod/TechDraw/Gui/TaskActiveView.ui b/src/Mod/TechDraw/Gui/TaskActiveView.ui
new file mode 100644
index 0000000000..03cacdbf78
--- /dev/null
+++ b/src/Mod/TechDraw/Gui/TaskActiveView.ui
@@ -0,0 +1,243 @@
+
+
+ TaskActiveView
+
+
+
+ 0
+ 0
+ 423
+ 317
+
+
+
+
+ 0
+ 0
+
+
+
+
+ 250
+ 0
+
+
+
+ ActiveView to TD View
+
+
+
+ :/icons/actions/techdraw-activeview.svg:/icons/actions/techdraw-activeview.svg
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ QFrame::Box
+
+
+ QFrame::Raised
+
+
+
-
+
+
-
+
+
+ QFormLayout::AllNonFixedFieldsGrow
+
+
-
+
+
+ Width
+
+
+
+ -
+
+
+ Width of generated view
+
+
+
+
+
+ 0.000000000000000
+
+
+ 297.000000000000000
+
+
+
+ -
+
+
+ Height
+
+
+
+ -
+
+
+ Border
+
+
+
+ -
+
+
+ Unused area around view
+
+
+
+
+
+ 0.000000000000000
+
+
+
+ -
+
+
+ Paint background yes/no
+
+
+ Background
+
+
+
+ -
+
+
+ Background color
+
+
+
+ -
+
+
+ Line Width
+
+
+
+ -
+
+
+ Width of lines in generated view.
+
+
+
+
+
+ 0.000000000000000
+
+
+ 0.500000000000000
+
+
+
+ -
+
+
+ Render Mode
+
+
+
+ -
+
+
+ Drawing style - see SoRenderManager
+
+
-
+
+ AS_IS
+
+
+ -
+
+ WIREFRAME
+
+
+ -
+
+ POINTS
+
+
+ -
+
+ WIREFRAME_OVERLAY
+
+
+ -
+
+ HIDDEN_LINE
+
+
+ -
+
+ BOUNDING_BOX
+
+
+
+
+ -
+
+
+ Height of generated view
+
+
+
+
+
+ 0.000000000000000
+
+
+ 210.000000000000000
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Gui::QuantitySpinBox
+ QWidget
+
+
+
+ Gui::ColorButton
+ QPushButton
+
+
+
+
+
+
+
+
diff --git a/src/Mod/TechDraw/Gui/Workbench.cpp b/src/Mod/TechDraw/Gui/Workbench.cpp
index 1ed47127a3..91d4898302 100644
--- a/src/Mod/TechDraw/Gui/Workbench.cpp
+++ b/src/Mod/TechDraw/Gui/Workbench.cpp
@@ -55,6 +55,7 @@ Gui::MenuItem* Workbench::setupMenuBar() const
*draw << "TechDraw_NewPage";
*draw << "Separator";
*draw << "TechDraw_NewView";
+ *draw << "TechDraw_NewActiveView";
// *draw << "TechDraw_NewMulti"; //deprecated
*draw << "TechDraw_ProjGroup";
*draw << "TechDraw_NewViewSection";
@@ -115,6 +116,7 @@ Gui::ToolBarItem* Workbench::setupToolBars() const
Gui::ToolBarItem *views = new Gui::ToolBarItem(root);
views->setCommand("TechDraw Views");
*views << "TechDraw_NewView";
+ *views << "TechDraw_NewActiveView";
// *views << "TechDraw_NewMulti"; //deprecated
*views << "TechDraw_ProjGroup";
*views << "TechDraw_NewViewSection";
@@ -184,6 +186,7 @@ Gui::ToolBarItem* Workbench::setupCommandBars() const
Gui::ToolBarItem *views = new Gui::ToolBarItem(root);
views->setCommand("Views");
*views << "TechDraw_NewView";
+ *views << "TechDraw_NewActiveView";
// *views << "TechDraw_NewMulti"; //deprecated
*views << "TechDraw_ProjGroup";
*views << "TechDraw_NewViewSection";