Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move image loading to core #8955

Merged
merged 14 commits into from Mar 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 0 additions & 1 deletion cMake/FreeCAD_Helpers/InitializeFreeCADBuildOptions.cmake
Expand Up @@ -108,7 +108,6 @@ macro(InitializeFreeCADBuildOptions)
option(BUILD_DRAFT "Build the FreeCAD draft module" ON)
option(BUILD_DRAWING "Build the FreeCAD drawing module" OFF)
option(BUILD_IDF "Build the FreeCAD idf module" ON)
option(BUILD_IMAGE "Build the FreeCAD image module" ON)
option(BUILD_IMPORT "Build the FreeCAD import module" ON)
option(BUILD_INSPECTION "Build the FreeCAD inspection module" ON)
option(BUILD_JTREADER "Build the FreeCAD jt reader module" OFF)
Expand Down
4 changes: 3 additions & 1 deletion src/App/Application.cpp
Expand Up @@ -94,6 +94,7 @@
#include "FeaturePython.h"
#include "GeoFeature.h"
#include "GeoFeatureGroupExtension.h"
#include "ImagePlane.h"
#include "InventorObject.h"
#include "Link.h"
#include "LinkBaseExtensionPy.h"
Expand All @@ -119,7 +120,7 @@
// If you stumble here, run the target "BuildExtractRevision" on Windows systems
// or the Python script "SubWCRev.py" on Linux based systems which builds
// src/Build/Version.h. Or create your own from src/Build/Version.h.in!
#include <Build/Version.h>

Check failure on line 123 in src/App/Application.cpp

View workflow job for this annotation

GitHub Actions / Lint / Lint

'Build/Version.h' file not found [clang-diagnostic-error]
#include "Branding.h"


Expand All @@ -140,7 +141,7 @@
# include <new>
#endif

FC_LOG_LEVEL_INIT("App", true, true)

Check warning on line 144 in src/App/Application.cpp

View workflow job for this annotation

GitHub Actions / Lint / Lint

variable '_s_fclvl' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]

using namespace App;
using namespace Base;
Expand All @@ -154,12 +155,12 @@
// Application
//==========================================================================

Base::Reference<ParameterManager> App::Application::_pcSysParamMngr;

Check warning on line 158 in src/App/Application.cpp

View workflow job for this annotation

GitHub Actions / Lint / Lint

variable '_pcSysParamMngr' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
Base::Reference<ParameterManager> App::Application::_pcUserParamMngr;

Check warning on line 159 in src/App/Application.cpp

View workflow job for this annotation

GitHub Actions / Lint / Lint

variable '_pcUserParamMngr' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
Base::ConsoleObserverStd *Application::_pConsoleObserverStd = nullptr;

Check warning on line 160 in src/App/Application.cpp

View workflow job for this annotation

GitHub Actions / Lint / Lint

variable '_pConsoleObserverStd' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]

Check warning on line 160 in src/App/Application.cpp

View workflow job for this annotation

GitHub Actions / Lint / Lint

variable '_pConsoleObserverStd' provides global access to a non-const object; consider making the pointed-to data 'const' [cppcoreguidelines-avoid-non-const-global-variables]
Base::ConsoleObserverFile *Application::_pConsoleObserverFile = nullptr;

Check warning on line 161 in src/App/Application.cpp

View workflow job for this annotation

GitHub Actions / Lint / Lint

variable '_pConsoleObserverFile' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]

Check warning on line 161 in src/App/Application.cpp

View workflow job for this annotation

GitHub Actions / Lint / Lint

variable '_pConsoleObserverFile' provides global access to a non-const object; consider making the pointed-to data 'const' [cppcoreguidelines-avoid-non-const-global-variables]

AppExport std::map<std::string, std::string> Application::mConfig;

Check warning on line 163 in src/App/Application.cpp

View workflow job for this annotation

GitHub Actions / Lint / Lint

variable 'mConfig' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]


//**************************************************************************
Expand Down Expand Up @@ -2053,12 +2054,13 @@
App::DocumentObjectGroup ::init();
App::DocumentObjectGroupPython ::init();
App::DocumentObjectFileIncluded::init();
App::ImagePlane ::init();
App::InventorObject ::init();
App::VRMLObject ::init();
App::Annotation ::init();
App::AnnotationLabel ::init();
App::MeasureDistance ::init();
App ::MaterialObject ::init();
App::MaterialObject ::init();
App::MaterialObjectPython ::init();
App::TextDocument ::init();
App::Placement ::init();
Expand Down
2 changes: 2 additions & 0 deletions src/App/CMakeLists.txt
Expand Up @@ -147,6 +147,7 @@ SET(Document_CPP_SRCS
GeoFeature.cpp
GeoFeatureGroupExtensionPyImp.cpp
GeoFeatureGroupExtension.cpp
ImagePlane.cpp
OriginGroupExtensionPyImp.cpp
OriginGroupExtension.cpp
PartPyImp.cpp
Expand Down Expand Up @@ -192,6 +193,7 @@ SET(Document_HPP_SRCS
FeatureTest.h
GeoFeature.h
GeoFeatureGroupExtension.h
ImagePlane.h
OriginGroupExtension.h
Part.h
Origin.h
Expand Down
23 changes: 20 additions & 3 deletions src/Mod/Image/App/ImagePlane.cpp → src/App/ImagePlane.cpp
Expand Up @@ -25,19 +25,36 @@
#include "ImagePlane.h"


using namespace Image;
using namespace App;

PROPERTY_SOURCE(Image::ImagePlane, App::GeoFeature)
PROPERTY_SOURCE(App::ImagePlane, App::GeoFeature)


ImagePlane::ImagePlane()
: XPixelsPerMeter{1000.0}
wwmayer marked this conversation as resolved.
Show resolved Hide resolved
, YPixelsPerMeter{1000.0}
{
ADD_PROPERTY_TYPE( ImageFile,(nullptr) , "ImagePlane",Prop_None,"File of the image");
ADD_PROPERTY_TYPE( XSize, (100), "ImagePlane",Prop_None,"Size of a pixel in X");
ADD_PROPERTY_TYPE( YSize, (100), "ImagePlane",Prop_None,"Size of a pixel in Y");
}

ImagePlane::~ImagePlane()
int ImagePlane::getXSizeInPixel()
{
return int(XSize.getValue() * XPixelsPerMeter / 1000);
}

int ImagePlane::getYSizeInPixel()
{
return int(YSize.getValue() * YPixelsPerMeter / 1000);
}

void ImagePlane::setXSizeInPixel(int value)
{
XSize.setValue(double(value) * 1000.0 / XPixelsPerMeter);
}

void ImagePlane::setYSizeInPixel(int value)
{
YSize.setValue(double(value) * 1000.0 / YPixelsPerMeter);
}
27 changes: 17 additions & 10 deletions src/Mod/Image/App/ImagePlane.h → src/App/ImagePlane.h
Expand Up @@ -20,37 +20,44 @@
* *
***************************************************************************/

#ifndef Image_ImagePlane_H
#define Image_ImagePlane_H
#ifndef App_ImagePlane_H
#define App_ImagePlane_H

#include <App/GeoFeature.h>
#include <App/PropertyFile.h>
#include <App/PropertyUnits.h>
#include <Mod/Image/ImageGlobal.h>

namespace Image
namespace App
{

class ImageExport ImagePlane : public App::GeoFeature
class AppExport ImagePlane : public App::GeoFeature
{
PROPERTY_HEADER_WITH_OVERRIDE(Image::ImagePlane);
PROPERTY_HEADER_WITH_OVERRIDE(App::ImagePlane);

public:
/// Constructor
ImagePlane();
~ImagePlane() override;
~ImagePlane() override = default;

App::PropertyFileIncluded ImageFile;
App::PropertyLength XSize;
App::PropertyLength YSize;

int getXSizeInPixel();
int getYSizeInPixel();
void setXSizeInPixel(int);
void setYSizeInPixel(int);

double XPixelsPerMeter;
double YPixelsPerMeter;

/// returns the type name of the ViewProvider
const char* getViewProviderName() const override {
return "ImageGui::ViewProviderImagePlane";
return "Gui::ViewProviderImagePlane";
}
};

} //namespace Image
} //namespace App


#endif // Image_ImagePlane_H
#endif // App_ImagePlane_H
20 changes: 20 additions & 0 deletions src/Gui/Application.cpp
Expand Up @@ -29,6 +29,7 @@
# include <QCloseEvent>
# include <QDir>
# include <QFileInfo>
# include <QImageReader>
# include <QLocale>
# include <QMessageBox>
# include <QMessageLogContext>
Expand Down Expand Up @@ -70,7 +71,7 @@
#include "ExpressionBindingPy.h"
#include "FileDialog.h"
#include "GuiApplication.h"
#include "GuiInitScript.h"

Check failure on line 74 in src/Gui/Application.cpp

View workflow job for this annotation

GitHub Actions / Lint / Lint

'GuiInitScript.h' file not found [clang-diagnostic-error]
#include "LinkViewPy.h"
#include "MainWindow.h"
#include "Macro.h"
Expand Down Expand Up @@ -101,6 +102,7 @@
#include "ViewProviderGeoFeatureGroup.h"
#include "ViewProviderGeometryObject.h"
#include "ViewProviderGroupExtension.h"
#include "ViewProviderImagePlane.h"
#include "ViewProviderInventorObject.h"
#include "ViewProviderLine.h"
#include "ViewProviderLink.h"
Expand Down Expand Up @@ -328,6 +330,22 @@

} // namespace Gui

namespace {
void setImportImageFormats()
{
QList<QByteArray> supportedFormats = QImageReader::supportedImageFormats();
std::stringstream str;
str << "Image formats (";
for (const auto& ext : supportedFormats) {
str << "*." << ext.constData() << " ";
}
str << ")";

std::string filter = str.str();
App::GetApplication().addImportType(filter.c_str(), "FreeCADGui");
}
}

Application::Application(bool GUIenabled)
{
//App::GetApplication().Attach(this);
Expand Down Expand Up @@ -1808,6 +1826,7 @@
Gui::ViewProviderDocumentObjectGroupPython ::init();
Gui::ViewProviderDragger ::init();
Gui::ViewProviderGeometryObject ::init();
Gui::ViewProviderImagePlane ::init();
Gui::ViewProviderInventorObject ::init();
Gui::ViewProviderVRMLObject ::init();
Gui::ViewProviderAnnotation ::init();
Expand Down Expand Up @@ -2053,8 +2072,8 @@
mw.setWindowTitle(mainApp.applicationName());
}

QObject::connect(&mainApp, SIGNAL(messageReceived(const QList<QByteArray> &)),

Check warning on line 2075 in src/Gui/Application.cpp

View workflow job for this annotation

GitHub Actions / Lint / Lint

QObject::connect(&mainApp, SIGNAL(messageReceived(const QList<QByteArray> &)), <--Consider using Functor-Based Connections
&mw, SLOT(processMessages(const QList<QByteArray> &)));

Check warning on line 2076 in src/Gui/Application.cpp

View workflow job for this annotation

GitHub Actions / Lint / Lint

&mw, SLOT(processMessages(const QList<QByteArray> &))); <--Consider using Functor-Based Connections

ParameterGrp::handle hDocGrp = WindowParameter::getDefaultParameter()->GetGroup("Document");
int timeout = hDocGrp->GetInt("AutoSaveTimeout", 15); // 15 min
Expand Down Expand Up @@ -2156,6 +2175,7 @@
try {
Base::Console().Log("Run Gui init script\n");
runInitGuiScript();
setImportImageFormats();
}
catch (const Base::Exception& e) {
Base::Console().Error("Error in FreeCADGuiInit.py: %s\n", e.what());
Expand Down Expand Up @@ -2243,7 +2263,7 @@
Instance->d->startingUp = false;

// gets called once we start the event loop
QTimer::singleShot(0, &mw, SLOT(delayedStartup()));

Check warning on line 2266 in src/Gui/Application.cpp

View workflow job for this annotation

GitHub Actions / Lint / Lint

QTimer::singleShot(0, &mw, SLOT(delayedStartup())); <--Consider using Functor-Based Connections

// run the Application event loop
Base::Console().Log("Init: Entering event loop\n");
Expand Down
115 changes: 7 additions & 108 deletions src/Gui/ApplicationPy.cpp
Expand Up @@ -51,6 +51,7 @@
#include "DocumentObserverPython.h"
#include "DownloadManager.h"
#include "EditorView.h"
#include "FileHandler.h"
#include "Macro.h"
#include "MainWindow.h"
#include "MainWindowPy.h"
Expand Down Expand Up @@ -494,7 +495,7 @@
break;
}
}
while(false);

Check warning on line 498 in src/Gui/ApplicationPy.cpp

View workflow job for this annotation

GitHub Actions / Lint / Lint

Empty loop bodies should use {} or continue [whitespace/empty_loop_body] [5]

if (!pcDoc) {
PyErr_SetString(PyExc_TypeError, "Either string or App.Document expected");
Expand Down Expand Up @@ -599,60 +600,9 @@
PyMem_Free(Name);
PY_TRY {
QString fileName = QString::fromUtf8(Utf8Name.c_str());
QFileInfo fi;
fi.setFile(fileName);
QString ext = fi.suffix().toLower();
QList<EditorView*> views = getMainWindow()->findChildren<EditorView*>();
for (QList<EditorView*>::Iterator it = views.begin(); it != views.end(); ++it) {
if ((*it)->fileName() == fileName) {
(*it)->setFocus();
Py_Return;
}
}

if (ext == QLatin1String("iv")) {
if (!Application::Instance->activeDocument())
App::GetApplication().newDocument();
//QString cmd = QString("Gui.activeDocument().addAnnotation(\"%1\",\"%2\")").arg(fi.baseName()).arg(fi.absoluteFilePath());
QString cmd = QString::fromLatin1(
"App.ActiveDocument.addObject(\"App::InventorObject\",\"%1\")."
"FileName=\"%2\"\n"
"App.ActiveDocument.ActiveObject.Label=\"%1\"\n"
"App.ActiveDocument.recompute()")
.arg(fi.baseName(), fi.absoluteFilePath());
Base::Interpreter().runString(cmd.toUtf8());
}
else if (ext == QLatin1String("wrl") ||
ext == QLatin1String("vrml") ||
ext == QLatin1String("wrz")) {
if (!Application::Instance->activeDocument())
App::GetApplication().newDocument();

// Add this to the search path in order to read inline files (#0002029)
QByteArray path = fi.absolutePath().toUtf8();
SoInput::addDirectoryFirst(path.constData());

//QString cmd = QString("Gui.activeDocument().addAnnotation(\"%1\",\"%2\")").arg(fi.baseName()).arg(fi.absoluteFilePath());
QString cmd = QString::fromLatin1(
"App.ActiveDocument.addObject(\"App::VRMLObject\",\"%1\")."
"VrmlFile=\"%2\"\n"
"App.ActiveDocument.ActiveObject.Label=\"%1\"\n"
"App.ActiveDocument.recompute()")
.arg(fi.baseName(), fi.absoluteFilePath());
Base::Interpreter().runString(cmd.toUtf8());
SoInput::removeDirectory(path.constData());
}
else if (ext == QLatin1String("py") ||
ext == QLatin1String("fcmacro") ||
ext == QLatin1String("fcscript")) {
auto editor = new PythonEditor();
editor->setWindowIcon(Gui::BitmapFactory().iconFromTheme("applications-python"));
auto edit = new PythonEditorView(editor, getMainWindow());
edit->open(fileName);
edit->resize(400, 300);
getMainWindow()->addWindow( edit );
}
else {
FileHandler handler(fileName);
if (!handler.openFile()) {
QString ext = handler.extension();
Base::Console().Error("File type '%s' not supported\n", ext.toLatin1().constData());
}
}
Expand All @@ -673,60 +623,9 @@

PY_TRY {
QString fileName = QString::fromUtf8(Utf8Name.c_str());
QFileInfo fi;
fi.setFile(fileName);
QString ext = fi.suffix().toLower();
if (ext == QLatin1String("iv")) {
App::Document *doc = nullptr;
if (DocName)
doc = App::GetApplication().getDocument(DocName);
else
doc = App::GetApplication().getActiveDocument();
if (!doc)
doc = App::GetApplication().newDocument(DocName);

App::DocumentObject* obj = doc->addObject("App::InventorObject",
(const char*)fi.baseName().toUtf8());
obj->Label.setValue((const char*)fi.baseName().toUtf8());
static_cast<App::PropertyString*>(obj->getPropertyByName("FileName"))
->setValue((const char*)fi.absoluteFilePath().toUtf8());
doc->recompute();
}
else if (ext == QLatin1String("wrl") ||
ext == QLatin1String("vrml") ||
ext == QLatin1String("wrz")) {
App::Document *doc = nullptr;
if (DocName)
doc = App::GetApplication().getDocument(DocName);
else
doc = App::GetApplication().getActiveDocument();
if (!doc)
doc = App::GetApplication().newDocument(DocName);

// Add this to the search path in order to read inline files (#0002029)
QByteArray path = fi.absolutePath().toUtf8();
SoInput::addDirectoryFirst(path.constData());

App::DocumentObject* obj = doc->addObject("App::VRMLObject",
(const char*)fi.baseName().toUtf8());
obj->Label.setValue((const char*)fi.baseName().toUtf8());
static_cast<App::PropertyFileIncluded*>(obj->getPropertyByName("VrmlFile"))
->setValue((const char*)fi.absoluteFilePath().toUtf8());
doc->recompute();

SoInput::removeDirectory(path.constData());
}
else if (ext == QLatin1String("py") ||
ext == QLatin1String("fcmacro") ||
ext == QLatin1String("fcscript")) {
auto editor = new PythonEditor();
editor->setWindowIcon(Gui::BitmapFactory().iconFromTheme("applications-python"));
auto edit = new PythonEditorView(editor, getMainWindow());
edit->open(fileName);
edit->resize(400, 300);
getMainWindow()->addWindow( edit );
}
else {
FileHandler handler(fileName);
if (!handler.importFile(std::string(DocName ? DocName : ""))) {
QString ext = handler.extension();
Base::Console().Error("File type '%s' not supported\n", ext.toLatin1().constData());
}
} PY_CATCH;
Expand Down