diff --git a/.gitattributes b/.gitattributes index 99557679b..e5dd84d85 100644 --- a/.gitattributes +++ b/.gitattributes @@ -14,3 +14,5 @@ UpdateResources.bat export-ignore BuildVersion.bat export-ignore *.sln export-ignore WindowsInstaller export-ignore +Version.h.in export-subst + diff --git a/CMakeLists.txt b/CMakeLists.txt index 473349a60..b52555629 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -56,15 +56,28 @@ endif(CMAKE_COMPILER_IS_GNUCXX) # ================================================================================ - +# Output directories for install target if(WIN32) - SET(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}) + SET(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/install CACHE PATH "Installation root directory") else(WIN32) - SET(CMAKE_INSTALL_PREFIX "/usr/lib${LIB_SUFFIX}/freecad") + SET(CMAKE_INSTALL_PREFIX "/usr/lib${LIB_SUFFIX}/freecad" CACHE PATH "Installation root directory") SET(INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib") endif(WIN32) +SET(CMAKE_INSTALL_DATADIR data CACHE PATH "Output directory for data and resource files") +SET(CMAKE_INSTALL_INCLUDEDIR include CACHE PATH "Output directory for header files") +SET(CMAKE_INSTALL_DOCDIR doc CACHE PATH "Output directory for documentation and license files") + +# used as compiler defines +SET(RESOURCEDIR "${CMAKE_INSTALL_DATADIR}") +SET(DOCDIR "${CMAKE_INSTALL_DOCDIR}") + +MESSAGE("prefix: ${CMAKE_INSTALL_PREFIX}") +MESSAGE("datadir: ${CMAKE_INSTALL_DATADIR}") +MESSAGE("docdir: ${CMAKE_INSTALL_DOCDIR}") +MESSAGE("includedir: ${CMAKE_INSTALL_INCLUDEDIR}") + # ============================================================================== # == Win32 is default behaviour use the LibPack copied in Source tree ========== if(MSVC) @@ -83,8 +96,7 @@ OPTION(FREECAD_MAINTAINERS_BUILD "Build FreeCAD for Maintainers, with Docu and 3 OPTION(FREECAD_BUILD_CAM "Build the FreeCAD CAM module and the needed libs, be aware, unfinished code!" OFF) OPTION(FREECAD_BUILD_FEM "Build the FreeCAD FEM module, be aware, unfinished code!" ON) OPTION(FREECAD_BUILD_SANDBOX "Build the FreeCAD Sandbox module which is only for testing purposes" OFF) -SET(RESOURCEDIR "${CMAKE_INSTALL_PREFIX}/data" CACHE PATH "Absolute path to the data directory.") -SET(DOCDIR "" CACHE PATH "Absolute path to the documentation directory.") +OPTION(FREECAD_BUILD_DEBIAN "Prepare for a build of a Debian package" OFF) # ============================================================================== @@ -443,7 +455,6 @@ if(FREECAD_MAINTAINERS_BUILD AND NOT WIN32) "Makefile$" "\\\\.sh$" "_CPack_" - "71" "config.h$" "config.log$" "config.status$" @@ -467,6 +478,7 @@ if(FREECAD_MAINTAINERS_BUILD AND NOT WIN32) #ADD_CUSTOM_TARGET(DIST make package_source) endif(FREECAD_MAINTAINERS_BUILD AND NOT WIN32) + #add_custom_target(dist COMMAND ${CMAKE_MAKE_PROGRAM} package_source) add_custom_target(dist-git COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_SOURCE_DIR}/src/Tools/makedist.py --srcdir=${CMAKE_SOURCE_DIR} --bindir=${CMAKE_BINARY_DIR} diff --git a/autogen.sh b/autogen.sh index 179104df8..cdc7f74d1 100755 --- a/autogen.sh +++ b/autogen.sh @@ -30,7 +30,7 @@ fi if which glibtoolize > /dev/null 2>&1; then echo "calling glibtoolize" glibtoolize --force --copy -elif which libtoolize > /dev/null 2>71; then +elif which libtoolize > /dev/null 2>&1; then echo "calling libtoolize" libtoolize --force --copy else diff --git a/cMake/FreeCadMacros.cmake b/cMake/FreeCadMacros.cmake index 09116f13b..5fa7680f7 100644 --- a/cMake/FreeCadMacros.cmake +++ b/cMake/FreeCadMacros.cmake @@ -38,37 +38,9 @@ ENDFOREACH(SRC ${FILES}) SET(${TARGETS} ${AddTargets}) ENDMACRO(COPY_IF_DIFFERENT FROM_DIR TO_DIR FILES TARGETS TAGS) -MACRO (fc_copy_to_mod_path mod_name ) - - FOREACH (it ${ARGN}) - file(TO_NATIVE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/${it}" NATIVE_SOURCE) - file(TO_NATIVE_PATH "${CMAKE_BINARY_DIR}/Mod/${mod_name}/" NATIVE_DEST) - message(STATUS "${PLATFORM_CP} ${NATIVE_SOURCE} ${NATIVE_DEST}") - if (WIN32) - else (WIN32) - execute_process( COMMAND ${PLATFORM_MK} ${NATIVE_DEST} ) - endif (WIN32) - execute_process( COMMAND ${PLATFORM_CP} ${NATIVE_SOURCE} ${NATIVE_DEST} ) - ENDFOREACH(it) -ENDMACRO(fc_copy_to_mod_path) - -MACRO (fc_copy_to_path path_name) - - FOREACH (it ${ARGN}) - file(TO_NATIVE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/${it}" NATIVE_SOURCE) - file(TO_NATIVE_PATH "${CMAKE_BINARY_DIR}/${path_name}/" NATIVE_DEST) - message(STATUS "${PLATFORM_CP} ${NATIVE_SOURCE} ${NATIVE_DEST}") - if (WIN32) - else (WIN32) - execute_process( COMMAND ${PLATFORM_MK} ${NATIVE_DEST} ) - endif (WIN32) - execute_process( COMMAND ${PLATFORM_CP} ${NATIVE_SOURCE} ${NATIVE_DEST} ) - ENDFOREACH(it) -ENDMACRO(fc_copy_to_path) - -MACRO (fc_copy_sources path_name mod_name) +MACRO (fc_copy_sources target_name outpath) foreach(it ${ARGN}) - file(TO_NATIVE_PATH "${CMAKE_BINARY_DIR}/${path_name}/${it}" outfile) + file(TO_NATIVE_PATH "${outpath}/${it}" outfile) get_filename_component(infile ${it} ABSOLUTE) get_filename_component(outfile ${outfile} ABSOLUTE) add_file_dependencies(${infile} ${outfile}) @@ -76,42 +48,21 @@ MACRO (fc_copy_sources path_name mod_name) SOURCE ${infile} COMMAND ${CMAKE_COMMAND} ARGS -E copy ${infile} ${outfile} - TARGET ${mod_name} + TARGET ${target_name} OUTPUTS ${outfile} ) endforeach(it) ADD_CUSTOM_COMMAND( - SOURCE ${mod_name} - TARGET ${mod_name} + SOURCE ${target_name} + TARGET ${target_name} DEPENDS ${ARGN} ) ENDMACRO(fc_copy_sources) -MACRO (fc_copy_sources_outpath out_path mod_name) +MACRO (fc_target_copy_resource target_name inpath outpath) foreach(it ${ARGN}) - file(TO_NATIVE_PATH "${CMAKE_BINARY_DIR}/${out_path}/${it}" outfile) - get_filename_component(infile ${it} ABSOLUTE) - get_filename_component(outfile ${outfile} ABSOLUTE) - add_file_dependencies(${infile} ${outfile}) - ADD_CUSTOM_COMMAND( - SOURCE ${infile} - COMMAND ${CMAKE_COMMAND} - ARGS -E copy ${infile} ${outfile} - TARGET ${mod_name} - OUTPUTS ${outfile} - ) - endforeach(it) - ADD_CUSTOM_COMMAND( - SOURCE ${mod_name} - TARGET ${mod_name} - DEPENDS ${ARGN} - ) -ENDMACRO(fc_copy_sources_outpath) - -MACRO (fc_copy_script path_name mod_name) - foreach(it ${ARGN}) - file(TO_NATIVE_PATH "${CMAKE_SOURCE_DIR}/src/${path_name}/${it}" infile) - file(TO_NATIVE_PATH "${CMAKE_BINARY_DIR}/${path_name}/${it}" outfile) + file(TO_NATIVE_PATH "${inpath}/${it}" infile) + file(TO_NATIVE_PATH "${outpath}/${it}" outfile) get_filename_component(infile ${infile} ABSOLUTE) get_filename_component(outfile ${outfile} ABSOLUTE) add_file_dependencies(${infile} ${outfile}) @@ -119,16 +70,16 @@ MACRO (fc_copy_script path_name mod_name) SOURCE ${infile} COMMAND ${CMAKE_COMMAND} ARGS -E copy ${infile} ${outfile} - TARGET ${mod_name} + TARGET ${target_name} OUTPUTS ${outfile} ) endforeach(it) ADD_CUSTOM_COMMAND( - SOURCE ${mod_name} - TARGET ${mod_name} + SOURCE ${target_name} + TARGET ${target_name} DEPENDS ${ARGN} ) -ENDMACRO(fc_copy_script) +ENDMACRO(fc_target_copy_resource) macro(copy_to_local_output_paths SOURCE_PATHS) if(CMAKE_CFG_INTDIR STREQUAL .) diff --git a/data/CMakeLists.txt b/data/CMakeLists.txt index 2d2cfee5f..fa8e5aa31 100644 --- a/data/CMakeLists.txt +++ b/data/CMakeLists.txt @@ -1 +1,9 @@ add_subdirectory(examples) + +INSTALL( + FILES + License.txt + DESTINATION + ${CMAKE_INSTALL_DATADIR} +) + diff --git a/data/examples/CMakeLists.txt b/data/examples/CMakeLists.txt index 0e3fadc43..9308e5728 100644 --- a/data/examples/CMakeLists.txt +++ b/data/examples/CMakeLists.txt @@ -2,6 +2,7 @@ SET(Examples_Files Schenkel.stp DrawingExample.FCStd + EngineBlock.FCStd PartDesignExample.FCStd RobotExample.FCStd ) @@ -10,12 +11,12 @@ ADD_CUSTOM_TARGET(Example_data ALL SOURCES ${Examples_Files} ) -fc_copy_sources("data/examples" "Examples" ${Examples_Files}) +fc_copy_sources(Examples "${CMAKE_BINARY_DIR}/data/examples" ${Examples_Files}) INSTALL( FILES ${Examples_Files} DESTINATION - data/examples + ${CMAKE_INSTALL_DATADIR}/examples ) diff --git a/src/3rdParty/CMakeLists.txt b/src/3rdParty/CMakeLists.txt index e6de70dba..5309c7a1f 100644 --- a/src/3rdParty/CMakeLists.txt +++ b/src/3rdParty/CMakeLists.txt @@ -20,16 +20,18 @@ elseif(FREECAD_BUILD_GUI AND FREECAD_LIBPACK_CHECKFILE7X) #endif(MINGW) # applies for Unix, MinGW and Windows with custom LibPack elseif(FREECAD_BUILD_GUI) - find_path(COIN_VERSION3 Inventor/scxml/ScXML.h ${COIN3D_INCLUDE_DIR}) - if (COIN_VERSION3) - if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/Pivy-0.5) - add_subdirectory(Pivy-0.5) - endif (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/Pivy-0.5) - else (COIN_VERSION3) - if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/Pivy) - add_subdirectory(Pivy) - endif (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/Pivy) - endif(COIN_VERSION3) + if (NOT FREECAD_BUILD_DEBIAN) + find_path(COIN_VERSION3 Inventor/scxml/ScXML.h ${COIN3D_INCLUDE_DIR}) + if (COIN_VERSION3) + if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/Pivy-0.5) + add_subdirectory(Pivy-0.5) + endif (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/Pivy-0.5) + else (COIN_VERSION3) + if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/Pivy) + add_subdirectory(Pivy) + endif (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/Pivy) + endif(COIN_VERSION3) + endif (NOT FREECAD_BUILD_DEBIAN) endif(FREECAD_BUILD_GUI AND FREECAD_LIBPACK_CHECKFILE6X) # For Windows we have all stuff in the LibPack diff --git a/src/3rdParty/Pivy-0.5/CMakeLists.txt b/src/3rdParty/Pivy-0.5/CMakeLists.txt index a58a09e72..3b71e24a1 100644 --- a/src/3rdParty/Pivy-0.5/CMakeLists.txt +++ b/src/3rdParty/Pivy-0.5/CMakeLists.txt @@ -56,15 +56,16 @@ else(MSVC) set_target_properties(coin PROPERTIES OUTPUT_NAME "_coin") set_target_properties(coin PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin/pivy) set_target_properties(coin PROPERTIES PREFIX "") - install(TARGETS coin DESTINATION bin/pivy) + set_target_properties(coin PROPERTIES INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/bin/pivy) endif(MSVC) -fc_copy_sources_outpath("bin/pivy" "coin" +fc_copy_sources(coin "${CMAKE_BINARY_DIR}/bin/pivy" __init__.py coin.py sogui.py ) +install(TARGETS coin DESTINATION bin/pivy) install(FILES __init__.py coin.py sogui.py DESTINATION bin/pivy) ########################### SoQtPy ########################### @@ -113,11 +114,13 @@ else(MSVC) set_target_properties(soqt PROPERTIES OUTPUT_NAME "_soqt") set_target_properties(soqt PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin/pivy/gui) set_target_properties(soqt PROPERTIES PREFIX "") + set_target_properties(soqt PROPERTIES INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/bin/pivy/gui) endif(MSVC) -fc_copy_sources_outpath("bin/pivy" "soqt" +fc_copy_sources(soqt "${CMAKE_BINARY_DIR}/bin/pivy" gui/soqt.py gui/__init__.py ) -install(FILES __init__.py soqt.py DESTINATION bin/pivy/gui) +install(TARGETS soqt DESTINATION bin/pivy/gui) +install(FILES gui/__init__.py soqt.py DESTINATION bin/pivy/gui) diff --git a/src/3rdParty/Pivy/CMakeLists.txt b/src/3rdParty/Pivy/CMakeLists.txt index dcdabdd5f..0094e725e 100644 --- a/src/3rdParty/Pivy/CMakeLists.txt +++ b/src/3rdParty/Pivy/CMakeLists.txt @@ -56,14 +56,16 @@ else(MSVC) set_target_properties(coin PROPERTIES OUTPUT_NAME "_coin") set_target_properties(coin PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin/pivy) set_target_properties(coin PROPERTIES PREFIX "") + set_target_properties(coin PROPERTIES INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/bin/pivy) endif(MSVC) -fc_copy_sources_outpath("bin/pivy" "coin" +fc_copy_sources(coin "${CMAKE_BINARY_DIR}/bin/pivy" __init__.py coin.py sogui.py ) +install(TARGETS coin DESTINATION bin/pivy) install(FILES __init__.py coin.py sogui.py DESTINATION bin/pivy) ########################### SoQtPy ########################### @@ -112,11 +114,13 @@ else(MSVC) set_target_properties(soqt PROPERTIES OUTPUT_NAME "_soqt") set_target_properties(soqt PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin/pivy/gui) set_target_properties(soqt PROPERTIES PREFIX "") + set_target_properties(soqt PROPERTIES INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/bin/pivy/gui) endif(MSVC) -fc_copy_sources_outpath("bin/pivy" "soqt" +fc_copy_sources(soqt "${CMAKE_BINARY_DIR}/bin/pivy" gui/soqt.py gui/__init__.py ) -install(FILES __init__.py gui/soqt.py DESTINATION bin/pivy/gui) +install(TARGETS soqt DESTINATION bin/pivy/gui) +install(FILES gui/__init__.py gui/soqt.py DESTINATION bin/pivy/gui) diff --git a/src/App/Application.cpp b/src/App/Application.cpp index bed1c143d..541203ab6 100644 --- a/src/App/Application.cpp +++ b/src/App/Application.cpp @@ -102,6 +102,7 @@ #include #include #include +#include using namespace App; using namespace std; @@ -481,8 +482,14 @@ std::string Application::getUserAppDataDir() std::string Application::getResourceDir() { -# ifdef RESOURCEDIR - return std::string(RESOURCEDIR) + "/"; +#ifdef RESOURCEDIR + std::string path(RESOURCEDIR); + path.append("/"); + QDir dir(QString::fromUtf8(RESOURCEDIR)); + if (dir.isAbsolute()) + return path; + else + return mConfig["AppHomePath"] + path; #else return mConfig["AppHomePath"]; #endif @@ -490,8 +497,14 @@ std::string Application::getResourceDir() std::string Application::getHelpDir() { -# ifdef DOCDIR - return std::string(DOCDIR) + "/"; +#ifdef DOCDIR + std::string path(DOCDIR); + path.append("/"); + QDir dir(QString::fromUtf8(DOCDIR)); + if (dir.isAbsolute()) + return path; + else + return mConfig["AppHomePath"] + path; #else return mConfig["DocPath"]; #endif diff --git a/src/App/CMakeLists.txt b/src/App/CMakeLists.txt index 9983266a8..5d1c2137c 100644 --- a/src/App/CMakeLists.txt +++ b/src/App/CMakeLists.txt @@ -4,13 +4,13 @@ if(WIN32) endif(WIN32) # This causes some problems with the resource files to be found, especially with the StartPage -#IF(RESOURCEDIR) -# add_definitions(-DRESOURCEDIR="${RESOURCEDIR}") -#ENDIF(RESOURCEDIR) +IF(RESOURCEDIR) + add_definitions(-DRESOURCEDIR="${RESOURCEDIR}") +ENDIF(RESOURCEDIR) -#IF(DOCDIR) -# add_definitions(-DDOCDIR="${DOCDIR}") -#ENDIF(DOCDIR) +IF(DOCDIR) + add_definitions(-DDOCDIR="${DOCDIR}") +ENDIF(DOCDIR) include_directories( ${CMAKE_BINARY_DIR}/src diff --git a/src/Base/CMakeLists.txt b/src/Base/CMakeLists.txt index 32612ca95..21f91d3ca 100644 --- a/src/Base/CMakeLists.txt +++ b/src/Base/CMakeLists.txt @@ -68,7 +68,7 @@ if(SWIG_FOUND) add_definitions(-DHAVE_SWIG=1) endif(SWIG_FOUND) -if (EXISTS ${CMAKE_SOURCE_DIR}/src/zipios++) +if (EXISTS ${CMAKE_SOURCE_DIR}/src/zipios++ AND NOT FREECAD_BUILD_DEBIAN) SET(zipios_SRCS ../zipios++/backbuffer.h ../zipios++/basicentry.cpp @@ -122,12 +122,12 @@ SET(zipios_SRCS ../zipios++/zipoutputstream.h ) SOURCE_GROUP("zipios" FILES ${zipios_SRCS}) -else (EXISTS ${CMAKE_SOURCE_DIR}/src/zipios++) +else (EXISTS ${CMAKE_SOURCE_DIR}/src/zipios++ AND NOT FREECAD_BUILD_DEBIAN) set(FreeCADBase_LIBS ${FreeCADBase_LIBS} -lzipios ) -endif (EXISTS ${CMAKE_SOURCE_DIR}/src/zipios++) +endif (EXISTS ${CMAKE_SOURCE_DIR}/src/zipios++ AND NOT FREECAD_BUILD_DEBIAN) SET(pycxx_SRCS ../CXX/Config.hxx diff --git a/src/Base/Vector3D.cpp b/src/Base/Vector3D.cpp index 4054ccb6e..fbc197f55 100644 --- a/src/Base/Vector3D.cpp +++ b/src/Base/Vector3D.cpp @@ -218,6 +218,28 @@ _Precision Vector3<_Precision>::DistanceToLine (const Vector3<_Precision> &rclBa return (_Precision) fabs((rclDirect % Vector3(*this - rclBase)).Length() / rclDirect.Length()); } +template +Vector3<_Precision> Vector3<_Precision>::DistanceToLineSegment (const Vector3& rclP1, + const Vector3& rclP2) const +{ + Vector3<_Precision> dir = rclP2-rclP1; + Vector3<_Precision> beg = *this-rclP1; + Vector3<_Precision> end = beg+dir; + + Vector3<_Precision> proj, len; + proj.ProjToLine(beg, dir); + len = proj + beg; + if (len * dir < 0 || len.Length() > dir.Length()) { + if (beg.Length() < end.Length()) + return beg; + else + return end; + } + else { + return proj; + } +} + template Vector3<_Precision>& Vector3<_Precision>::ProjToLine (const Vector3<_Precision> &rclPoint, const Vector3<_Precision> &rclLine) diff --git a/src/Base/Vector3D.h b/src/Base/Vector3D.h index 57418d359..395d5afe6 100644 --- a/src/Base/Vector3D.h +++ b/src/Base/Vector3D.h @@ -180,6 +180,12 @@ public: _Precision DistanceToPlane (const Vector3 &rclBase, const Vector3 &rclNorm) const; /// Computes the distance from this point to the line given by \a rclBase and \a rclDirect. _Precision DistanceToLine (const Vector3 &rclBase, const Vector3 &rclDirect) const; + /** Computes the vector from this point to the point on the line segment with the shortest + * distance. The line segment is defined by \a rclP1 and \a rclP2. + * Note: If the projection of this point is outside the segment then the shortest distance + * to \a rclP1 or \a rclP2 is computed. + */ + Vector3 DistanceToLineSegment (const Vector3& rclP1, const Vector3& rclP2) const; //@} }; diff --git a/src/Build/Version.h.in b/src/Build/Version.h.in index ac7a33ee4..d76718751 100644 --- a/src/Build/Version.h.in +++ b/src/Build/Version.h.in @@ -3,7 +3,7 @@ #define FCVersionMajor "0" #define FCVersionMinor "13" #define FCVersionName "Vulcan" - +// test: $Format:Hash (%H), Date: %ci$ #define FCRevision "$WCREV$" //Highest committed revision number #define FCRevisionDate "$WCDATE$" //Date of highest committed revision #define FCRepositoryURL "$WCURL$" //Repository URL of the working copy diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a9e9915b3..88a57d35b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -12,10 +12,15 @@ if(FREECAD_BUILD_GUI) configure_file(Doc/freecad.qch ${CMAKE_BINARY_DIR}/doc/freecad.qch COPYONLY) endif(FREECAD_BUILD_GUI) -#if(FREECAD_MAINTAINERS_BUILD) +if(FREECAD_MAINTAINERS_BUILD) add_subdirectory(Doc) -#endif(FREECAD_MAINTAINERS_BUILD) +endif(FREECAD_MAINTAINERS_BUILD) if(FREECAD_MAINTAINERS_BUILD AND WIN32) #add_subdirectory(WindowsInstaller) endif(FREECAD_MAINTAINERS_BUILD AND WIN32) + +INSTALL(FILES Doc/Start_Page.html Doc/freecad.qhc Doc/freecad.qch + DESTINATION ${CMAKE_INSTALL_DOCDIR} +) + diff --git a/src/Gui/BlenderNavigationStyle.cpp b/src/Gui/BlenderNavigationStyle.cpp index aeb875c80..d40ab1acc 100644 --- a/src/Gui/BlenderNavigationStyle.cpp +++ b/src/Gui/BlenderNavigationStyle.cpp @@ -257,17 +257,11 @@ SbBool BlenderNavigationStyle::processSoEvent(const SoEvent * const ev) this->button3down = press; break; case SoMouseButtonEvent::BUTTON4: - if (this->invertZoom) - zoom(viewer->getCamera(), -0.05f); - else - zoom(viewer->getCamera(), 0.05f); + doZoom(viewer->getCamera(), TRUE, posn); processed = TRUE; break; case SoMouseButtonEvent::BUTTON5: - if (this->invertZoom) - zoom(viewer->getCamera(), 0.05f); - else - zoom(viewer->getCamera(), -0.05f); + doZoom(viewer->getCamera(), FALSE, posn); processed = TRUE; break; default: diff --git a/src/Gui/CADNavigationStyle.cpp b/src/Gui/CADNavigationStyle.cpp index 965ace1bf..99f0d5919 100644 --- a/src/Gui/CADNavigationStyle.cpp +++ b/src/Gui/CADNavigationStyle.cpp @@ -286,17 +286,11 @@ SbBool CADNavigationStyle::processSoEvent(const SoEvent * const ev) this->button3down = press; break; case SoMouseButtonEvent::BUTTON4: - if (this->invertZoom) - zoom(viewer->getCamera(), -0.05f); - else - zoom(viewer->getCamera(), 0.05f); + doZoom(viewer->getCamera(), TRUE, posn); processed = TRUE; break; case SoMouseButtonEvent::BUTTON5: - if (this->invertZoom) - zoom(viewer->getCamera(), 0.05f); - else - zoom(viewer->getCamera(), -0.05f); + doZoom(viewer->getCamera(), FALSE, posn); processed = TRUE; break; default: diff --git a/src/Gui/CMakeLists.txt b/src/Gui/CMakeLists.txt index b0e8968b5..133d81a54 100644 --- a/src/Gui/CMakeLists.txt +++ b/src/Gui/CMakeLists.txt @@ -848,4 +848,8 @@ else(WIN32) INSTALL(TARGETS FreeCADGui LIBRARY DESTINATION lib ) + INSTALL(FILES Icons/freecad.xpm Icons/freecad-doc.png + DESTINATION ${CMAKE_INSTALL_DATADIR} + ) endif(WIN32) + diff --git a/src/Gui/CommandDoc.cpp b/src/Gui/CommandDoc.cpp index 8e1e79cfb..8bbe611c0 100644 --- a/src/Gui/CommandDoc.cpp +++ b/src/Gui/CommandDoc.cpp @@ -52,6 +52,8 @@ #include "Placement.h" #include "WaitCursor.h" #include "ViewProvider.h" +#include +#include #include "MergeDocuments.h" using namespace Gui; @@ -1022,6 +1024,46 @@ bool StdCmdPlacement::isActive(void) return (Gui::Control().activeDialog()==0); } +//=========================================================================== +// Std_Edit +//=========================================================================== +DEF_STD_CMD_A(StdCmdEdit); + +StdCmdEdit::StdCmdEdit() + :Command("Std_Edit") +{ + sGroup = QT_TR_NOOP("Edit"); + sMenuText = QT_TR_NOOP("Toggle &Editmode"); + sToolTipText = QT_TR_NOOP("Toggles the selected object's edit mode"); + sWhatsThis = "Std_Edit"; + sStatusTip = QT_TR_NOOP("Enters or leaves the selected object's edit mode"); +#if QT_VERSION >= 0x040200 + sPixmap = "edit-edit"; +#endif + eType = ForEdit; +} + +void StdCmdEdit::activated(int iMsg) +{ + Gui::MDIView* view = Gui::getMainWindow()->activeWindow(); + if (view && view->isDerivedFrom(Gui::View3DInventor::getClassTypeId())) { + Gui::View3DInventorViewer* viewer = static_cast(view)->getViewer(); + if (viewer->isEditingViewProvider()) { + doCommand(Command::Gui,"Gui.activeDocument().resetEdit()"); + } else { + if (Selection().getCompleteSelection().size() > 0) { + SelectionSingleton::SelObj obj = Selection().getCompleteSelection()[0]; + doCommand(Command::Gui,"Gui.activeDocument().setEdit(\"%s\",0)",obj.FeatName); + } + } + } +} + +bool StdCmdEdit::isActive(void) +{ + return (Selection().getCompleteSelection().size() > 0) || (Gui::Control().activeDialog() != 0); +} + namespace Gui { @@ -1054,6 +1096,7 @@ void CreateDocCommands(void) rcCmdMgr.addCommand(new StdCmdRefresh()); rcCmdMgr.addCommand(new StdCmdTransform()); rcCmdMgr.addCommand(new StdCmdPlacement()); + rcCmdMgr.addCommand(new StdCmdEdit()); } } // namespace Gui diff --git a/src/Gui/DlgSettings3DView.ui b/src/Gui/DlgSettings3DView.ui index 7cad6e9aa..66b80e72c 100644 --- a/src/Gui/DlgSettings3DView.ui +++ b/src/Gui/DlgSettings3DView.ui @@ -7,7 +7,7 @@ 0 0 477 - 442 + 495 @@ -25,7 +25,7 @@ 3D View settings - + @@ -130,6 +130,65 @@ + + + + + Zoom at cursor + + + ZoomAtCursor + + + View + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Zoom step + + + + + + + 0.010000000000000 + + + 1.000000000000000 + + + 0.050000000000000 + + + 0.050000000000000 + + + ZoomStep + + + View + + + + + + Invert zoom @@ -142,7 +201,7 @@ - + Enable anti-aliasing (slower) @@ -155,7 +214,7 @@ - + QFrame::HLine @@ -168,7 +227,7 @@ - + 6 @@ -210,7 +269,7 @@ - + 11 @@ -399,6 +458,8 @@ comboNavigationStyle mouseButton comboOrbitStyle + checkBoxZoomAtCursor + spinBoxZoomStep checkBoxInvertZoom checkBoxAntiAliasing FloatSpinBox_EyeDistance diff --git a/src/Gui/DlgSettings3DViewImp.cpp b/src/Gui/DlgSettings3DViewImp.cpp index 6b6ed6a86..604c35081 100644 --- a/src/Gui/DlgSettings3DViewImp.cpp +++ b/src/Gui/DlgSettings3DViewImp.cpp @@ -72,7 +72,9 @@ void DlgSettings3DViewImp::saveSettings() int index = comboOrbitStyle->currentIndex(); hGrp->SetInt("OrbitStyle", index); + checkBoxZoomAtCursor->onSave(); checkBoxInvertZoom->onSave(); + spinBoxZoomStep->onSave(); checkBoxAntiAliasing->onSave(); CheckBox_CornerCoordSystem->onSave(); CheckBox_ShowFPS->onSave(); @@ -87,7 +89,9 @@ void DlgSettings3DViewImp::saveSettings() void DlgSettings3DViewImp::loadSettings() { + checkBoxZoomAtCursor->onRestore(); checkBoxInvertZoom->onRestore(); + spinBoxZoomStep->onRestore(); checkBoxAntiAliasing->onRestore(); CheckBox_CornerCoordSystem->onRestore(); CheckBox_ShowFPS->onRestore(); diff --git a/src/Gui/Icons/edit-edit.svg b/src/Gui/Icons/edit-edit.svg new file mode 100644 index 000000000..d63fb7ce7 --- /dev/null +++ b/src/Gui/Icons/edit-edit.svg @@ -0,0 +1,149 @@ + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/src/Gui/Icons/resource.qrc b/src/Gui/Icons/resource.qrc index 78a314d16..82548cd39 100644 --- a/src/Gui/Icons/resource.qrc +++ b/src/Gui/Icons/resource.qrc @@ -45,6 +45,7 @@ edit-select-all.svg edit-redo.svg edit-undo.svg + edit-edit.svg help-browser.svg preferences-system.svg window-new.svg diff --git a/src/Gui/InventorNavigationStyle.cpp b/src/Gui/InventorNavigationStyle.cpp index 42993e755..5fb72f989 100644 --- a/src/Gui/InventorNavigationStyle.cpp +++ b/src/Gui/InventorNavigationStyle.cpp @@ -251,17 +251,11 @@ SbBool InventorNavigationStyle::processSoEvent(const SoEvent * const ev) this->button3down = press; break; case SoMouseButtonEvent::BUTTON4: - if (this->invertZoom) - zoom(viewer->getCamera(), -0.05f); - else - zoom(viewer->getCamera(), 0.05f); + doZoom(viewer->getCamera(), TRUE, posn); processed = TRUE; break; case SoMouseButtonEvent::BUTTON5: - if (this->invertZoom) - zoom(viewer->getCamera(), 0.05f); - else - zoom(viewer->getCamera(), -0.05f); + doZoom(viewer->getCamera(), FALSE, posn); processed = TRUE; break; default: diff --git a/src/Gui/Macro.cpp b/src/Gui/Macro.cpp index a7285008e..f0d6658d9 100644 --- a/src/Gui/Macro.cpp +++ b/src/Gui/Macro.cpp @@ -197,15 +197,19 @@ namespace Gui { public: PythonRedirector(const char* type, PyObject* obj) : std_out(type), out(obj) { - Base::PyGILStateLocker lock; - old = PySys_GetObject(const_cast(std_out)); - PySys_SetObject(const_cast(std_out), obj); + if (out) { + Base::PyGILStateLocker lock; + old = PySys_GetObject(const_cast(std_out)); + PySys_SetObject(const_cast(std_out), out); + } } ~PythonRedirector() { - Base::PyGILStateLocker lock; - PySys_SetObject(const_cast(std_out), old); - Py_XDECREF(out); + if (out) { + Base::PyGILStateLocker lock; + PySys_SetObject(const_cast(std_out), old); + Py_DECREF(out); + } } private: const char* std_out; @@ -217,8 +221,12 @@ namespace Gui { void MacroManager::run(MacroType eType,const char *sName) { try { - PythonRedirector std_out("stdout",new OutputStdout); - PythonRedirector std_err("stderr",new OutputStderr); + ParameterGrp::handle hGrp = App::GetApplication().GetUserParameter() + .GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("OutputWindow"); + PyObject* pyout = hGrp->GetBool("RedirectPythonOutput") ? new OutputStdout : 0; + PyObject* pyerr = hGrp->GetBool("RedirectPythonErrors") ? new OutputStderr : 0; + PythonRedirector std_out("stdout",pyout); + PythonRedirector std_err("stderr",pyerr); //The given path name is expected to be Utf-8 Base::Interpreter().runFile(sName, true); } diff --git a/src/Gui/MainWindow.cpp b/src/Gui/MainWindow.cpp index 6b34086d5..b36d3e661 100644 --- a/src/Gui/MainWindow.cpp +++ b/src/Gui/MainWindow.cpp @@ -36,6 +36,7 @@ # include # include # include +# include # include # include # include @@ -1303,6 +1304,44 @@ QPixmap MainWindow::splashImage() const splash_image.load(fi.filePath(), "PNG"); if (splash_image.isNull()) splash_image = Gui::BitmapFactory().pixmap(App::Application::Config()["SplashPicture"].c_str()); + + // include application name and version number + std::map::const_iterator tc = App::Application::Config().find("SplashExeColor"); + if (tc != App::Application::Config().end()) { + QString exeName = QString::fromAscii(App::Application::Config()["ExeName"].c_str()); + QString major = QString::fromAscii(App::Application::Config()["BuildVersionMajor"].c_str()); + QString minor = QString::fromAscii(App::Application::Config()["BuildVersionMinor"].c_str()); + QString version = QString::fromAscii("%1.%2").arg(major).arg(minor); + + QPainter painter; + painter.begin(&splash_image); + QFont fontExe = painter.font(); + fontExe.setPointSize(20); + QFontMetrics metricExe(fontExe); + int l = metricExe.width(exeName); + int w = splash_image.width(); + int h = splash_image.height(); + + QFont fontVer = painter.font(); + fontVer.setPointSize(12); + QFontMetrics metricVer(fontVer); + int v = metricVer.width(version); + + QColor color; + color.setNamedColor(QString::fromAscii(tc->second.c_str())); + if (!color.isValid()) { + color.setRed(200); + color.setGreen(200); + color.setBlue(200); + } + painter.setPen(color); + painter.setFont(fontExe); + painter.drawText(w-(l+v+10),h-20, exeName); + painter.setFont(fontVer); + painter.drawText(w-(v+5),h-20, version); + painter.end(); + } + return splash_image; } diff --git a/src/Gui/NavigationStyle.cpp b/src/Gui/NavigationStyle.cpp index c5283e00f..34bec5184 100644 --- a/src/Gui/NavigationStyle.cpp +++ b/src/Gui/NavigationStyle.cpp @@ -215,6 +215,10 @@ void NavigationStyle::initialize() this->altdown = FALSE; this->invertZoom = App::GetApplication().GetParameterGroupByPath ("User parameter:BaseApp/Preferences/View")->GetBool("InvertZoom",false); + this->zoomAtCursor = App::GetApplication().GetParameterGroupByPath + ("User parameter:BaseApp/Preferences/View")->GetBool("ZoomAtCursor",false); + this->zoomStep = App::GetApplication().GetParameterGroupByPath + ("User parameter:BaseApp/Preferences/View")->GetFloat("ZoomStep",0.05f); } void NavigationStyle::finalize() @@ -709,6 +713,33 @@ void NavigationStyle::zoomByCursor(const SbVec2f & thispos, const SbVec2f & prev zoom(viewer->getCamera(), (thispos[1] - prevpos[1]) * 10.0f/*20.0f*/); } +void NavigationStyle::doZoom(SoCamera* camera, SbBool forward, const SbVec2f& pos) +{ + SbBool zoomAtCur = this->zoomAtCursor; + if (zoomAtCur) { + const SbViewportRegion & vp = viewer->getViewportRegion(); + float ratio = vp.getViewportAspectRatio(); + SbViewVolume vv = camera->getViewVolume(vp.getViewportAspectRatio()); + SbPlane panplane = vv.getPlane(camera->focalDistance.getValue()); + panCamera(viewer->getCamera(), ratio, panplane, SbVec2f(0.5,0.5), pos); + } + + float value = this->zoomStep; + if (!forward) + value = -value; + if (this->invertZoom) + value = -value; + zoom(camera, value); + + if (zoomAtCur) { + const SbViewportRegion & vp = viewer->getViewportRegion(); + float ratio = vp.getViewportAspectRatio(); + SbViewVolume vv = camera->getViewVolume(vp.getViewportAspectRatio()); + SbPlane panplane = vv.getPlane(camera->focalDistance.getValue()); + panCamera(viewer->getCamera(), ratio, panplane, pos, SbVec2f(0.5,0.5)); + } +} + /** Uses the sphere sheet projector to map the mouseposition onto * a 3D point and find a rotation from this and the last calculated point. */ @@ -884,6 +915,21 @@ SbBool NavigationStyle::isZoomInverted() const return this->invertZoom; } +void NavigationStyle::setZoomStep(float val) +{ + this->zoomStep = val; +} + +void NavigationStyle::setZoomAtCursor(SbBool on) +{ + this->zoomAtCursor = on; +} + +SbBool NavigationStyle::isZoomAtCursor() const +{ + return this->zoomAtCursor; +} + void NavigationStyle::startSelection(AbstractMouseSelection* mouse) { if (!mouse) diff --git a/src/Gui/NavigationStyle.h b/src/Gui/NavigationStyle.h index 5b7087ef1..846e65f86 100644 --- a/src/Gui/NavigationStyle.h +++ b/src/Gui/NavigationStyle.h @@ -111,6 +111,9 @@ public: void setZoomInverted(SbBool); SbBool isZoomInverted() const; + void setZoomStep(float); + void setZoomAtCursor(SbBool); + SbBool isZoomAtCursor() const; void updateAnimation(); void redraw(); @@ -162,6 +165,7 @@ protected: void panToCenter(const SbPlane & pplane, const SbVec2f & currpos); void zoom(SoCamera * camera, float diffvalue); void zoomByCursor(const SbVec2f & thispos, const SbVec2f & prevpos); + void doZoom(SoCamera * camera, SbBool forward, const SbVec2f& pos); void spin(const SbVec2f & pointerpos); SbBool doSpin(); @@ -191,6 +195,8 @@ protected: SbBool ctrldown, shiftdown, altdown; SbBool button1down, button2down, button3down; SbBool invertZoom; + SbBool zoomAtCursor; + float zoomStep; /** @name Mouse model */ //@{ diff --git a/src/Gui/TouchpadNavigationStyle.cpp b/src/Gui/TouchpadNavigationStyle.cpp index e192e11d6..530b0650d 100644 --- a/src/Gui/TouchpadNavigationStyle.cpp +++ b/src/Gui/TouchpadNavigationStyle.cpp @@ -154,17 +154,11 @@ SbBool TouchpadNavigationStyle::processSoEvent(const SoEvent * const ev) this->setViewing(true); break; case SoKeyboardEvent::PAGE_UP: - if (this->invertZoom) - zoom(viewer->getCamera(), 0.05f); - else - zoom(viewer->getCamera(), -0.05f); + doZoom(viewer->getCamera(), TRUE, posn); processed = TRUE; break; case SoKeyboardEvent::PAGE_DOWN: - if (this->invertZoom) - zoom(viewer->getCamera(), -0.05f); - else - zoom(viewer->getCamera(), 0.05f); + doZoom(viewer->getCamera(), FALSE, posn); processed = TRUE; break; default: diff --git a/src/Gui/View3DInventor.cpp b/src/Gui/View3DInventor.cpp index 0b9f870bf..262916d1e 100644 --- a/src/Gui/View3DInventor.cpp +++ b/src/Gui/View3DInventor.cpp @@ -276,6 +276,14 @@ void View3DInventor::OnChange(ParameterGrp::SubjectType &rCaller,ParameterGrp::M bool on = rGrp.GetBool("InvertZoom", false); _viewer->navigationStyle()->setZoomInverted(on); } + else if (strcmp(Reason,"ZoomAtCursor") == 0) { + bool on = rGrp.GetBool("ZoomAtCursor", false); + _viewer->navigationStyle()->setZoomAtCursor(on); + } + else if (strcmp(Reason,"ZoomSetp") == 0) { + float val = rGrp.GetFloat("ZoomSetp", 0.0f); + _viewer->navigationStyle()->setZoomStep(val); + } else if (strcmp(Reason,"EyeDistance") == 0) { _viewer->setStereoOffset(rGrp.GetFloat("EyeDistance",65.0)); } diff --git a/src/Gui/Workbench.cpp b/src/Gui/Workbench.cpp index b3e1115d0..749278fb0 100644 --- a/src/Gui/Workbench.cpp +++ b/src/Gui/Workbench.cpp @@ -440,7 +440,7 @@ MenuItem* StdWorkbench::setupMenuBar() const *edit << "Std_Undo" << "Std_Redo" << "Separator" << "Std_Cut" << "Std_Copy" << "Std_Paste" << "Std_DuplicateSelection" << "Separator" << "Std_Refresh" << "Std_SelectAll" << "Std_Delete" << "Std_Placement" - << "Separator" << "Std_DlgPreferences"; + << "Std_Edit" << "Separator" << "Std_DlgPreferences"; // Standard views MenuItem* stdviews = new MenuItem; diff --git a/src/Main/MainGui.cpp b/src/Main/MainGui.cpp index 8a46d6cc2..7d898cfe7 100644 --- a/src/Main/MainGui.cpp +++ b/src/Main/MainGui.cpp @@ -276,6 +276,7 @@ int main( int argc, char ** argv ) //App::Application::Config()["HiddenDockWindow"] = "Property editor"; App::Application::Config()["SplashAlignment" ] = "Bottom|Left"; App::Application::Config()["SplashTextColor" ] = "#ffffff"; // white + App::Application::Config()["SplashExeColor" ] = "#c8c8c8"; // light grey try { // Init phase =========================================================== diff --git a/src/Mod/Arch/ArchAxis.py b/src/Mod/Arch/ArchAxis.py index 53b425b75..dc9cca650 100644 --- a/src/Mod/Arch/ArchAxis.py +++ b/src/Mod/Arch/ArchAxis.py @@ -340,10 +340,9 @@ class _AxisTaskPanel: self.obj.Angles = a FreeCAD.ActiveDocument.recompute() - def finish(self): + def accept(self): self.resetObject() - if self.obj: - self.obj.ViewObject.finishEditing() + FreeCADGui.ActiveDocument.resetEdit() def retranslateUi(self, TaskPanel): TaskPanel.setWindowTitle(QtGui.QApplication.translate("Arch", "Axes", None, QtGui.QApplication.UnicodeUTF8)) diff --git a/src/Mod/Arch/ArchComponent.py b/src/Mod/Arch/ArchComponent.py index 6b8b33af1..b6065fa04 100644 --- a/src/Mod/Arch/ArchComponent.py +++ b/src/Mod/Arch/ArchComponent.py @@ -222,8 +222,7 @@ class ComponentTaskPanel: def accept(self): FreeCAD.ActiveDocument.recompute() - if self.obj: - self.obj.ViewObject.finishEditing() + FreeCADGui.ActiveDocument.resetEdit() return True def editObject(self,wid,col): @@ -308,7 +307,7 @@ class ViewProviderComponent: def unsetEdit(self,vobj,mode): FreeCADGui.Control.closeDialog() - return + return False class ArchSelectionObserver: def __init__(self,origin,watched): diff --git a/src/Mod/Arch/CMakeLists.txt b/src/Mod/Arch/CMakeLists.txt index 73f45b793..0e924ec08 100644 --- a/src/Mod/Arch/CMakeLists.txt +++ b/src/Mod/Arch/CMakeLists.txt @@ -28,7 +28,7 @@ ADD_CUSTOM_TARGET(Arch ALL SOURCES ${all_files} ) -fc_copy_sources("Mod/Arch" "Arch" ${all_files}) +fc_copy_sources(Arch "${CMAKE_BINARY_DIR}/Mod/Arch" ${all_files}) INSTALL( FILES ${Arch_SRCS} diff --git a/src/Mod/Assembly/App/CMakeLists.txt b/src/Mod/Assembly/App/CMakeLists.txt index 65d1a8ad4..d800cba35 100644 --- a/src/Mod/Assembly/App/CMakeLists.txt +++ b/src/Mod/Assembly/App/CMakeLists.txt @@ -23,7 +23,12 @@ SET(Assembly_SRCS add_library(Assembly SHARED ${Assembly_SRCS}) target_link_libraries(Assembly ${Assembly_LIBS}) -fc_copy_script("Mod/Assembly" "Assembly" Init.py) + + +fc_target_copy_resource(Assembly + ${CMAKE_SOURCE_DIR}/src/Mod/Assembly + ${CMAKE_BINARY_DIR}/Mod/Assembly + Init.py) if(MSVC) set_target_properties(Assembly PROPERTIES SUFFIX ".pyd") diff --git a/src/Mod/Assembly/Gui/CMakeLists.txt b/src/Mod/Assembly/Gui/CMakeLists.txt index 9a734ffd3..9d5daf67d 100644 --- a/src/Mod/Assembly/Gui/CMakeLists.txt +++ b/src/Mod/Assembly/Gui/CMakeLists.txt @@ -33,7 +33,12 @@ SET(AssemblyGui_SRCS add_library(AssemblyGui SHARED ${AssemblyGui_SRCS}) target_link_libraries(AssemblyGui ${AssemblyGui_LIBS}) -fc_copy_script("Mod/Assembly" "AssemblyGui" InitGui.py) + + +fc_target_copy_resource(AssemblyGui + ${CMAKE_SOURCE_DIR}/src/Mod/Assembly + ${CMAKE_BINARY_DIR}/Mod/Assembly + InitGui.py) if(MSVC) set_target_properties(AssemblyGui PROPERTIES SUFFIX ".pyd") diff --git a/src/Mod/Complete/App/CMakeLists.txt b/src/Mod/Complete/App/CMakeLists.txt index 09cc9db4a..5295f92bd 100644 --- a/src/Mod/Complete/App/CMakeLists.txt +++ b/src/Mod/Complete/App/CMakeLists.txt @@ -23,7 +23,12 @@ SET(Complete_SRCS add_library(Complete SHARED ${Complete_SRCS}) target_link_libraries(Complete ${Complete_LIBS}) -fc_copy_script("Mod/Complete" "Complete" Init.py) + + +fc_target_copy_resource(Complete + ${CMAKE_SOURCE_DIR}/src/Mod/Complete + ${CMAKE_BINARY_DIR}/Mod/Complete + Init.py) if(MSVC) set_target_properties(Complete PROPERTIES SUFFIX ".pyd") diff --git a/src/Mod/Complete/Gui/CMakeLists.txt b/src/Mod/Complete/Gui/CMakeLists.txt index 5a386d7d5..f3bd769cd 100644 --- a/src/Mod/Complete/Gui/CMakeLists.txt +++ b/src/Mod/Complete/Gui/CMakeLists.txt @@ -29,7 +29,12 @@ SET(CompleteGui_SRCS add_library(CompleteGui SHARED ${CompleteGui_SRCS}) target_link_libraries(CompleteGui ${CompleteGui_LIBS}) -fc_copy_script("Mod/Complete" "CompleteGui" InitGui.py) + + +fc_target_copy_resource(CompleteGui + ${CMAKE_SOURCE_DIR}/src/Mod/Complete + ${CMAKE_BINARY_DIR}/Mod/Complete + InitGui.py) if(MSVC) set_target_properties(CompleteGui PROPERTIES SUFFIX ".pyd") diff --git a/src/Mod/Draft/CMakeLists.txt b/src/Mod/Draft/CMakeLists.txt index fc50e12fc..99e27d0f9 100644 --- a/src/Mod/Draft/CMakeLists.txt +++ b/src/Mod/Draft/CMakeLists.txt @@ -34,7 +34,7 @@ ADD_CUSTOM_TARGET(Draft ALL SOURCES ${all_files} ) -fc_copy_sources("Mod/Draft" "Draft" ${all_files}) +fc_copy_sources(Draft "${CMAKE_BINARY_DIR}/Mod/Draft" ${all_files}) INSTALL( diff --git a/src/Mod/Draft/Draft.py b/src/Mod/Draft/Draft.py index 3e733d387..9fce6f8c6 100644 --- a/src/Mod/Draft/Draft.py +++ b/src/Mod/Draft/Draft.py @@ -100,7 +100,8 @@ def getParamType(param): return "string" elif param in ["textheight","tolerance","gridSpacing"]: return "float" - elif param in ["selectBaseObjects","alwaysSnap","grid","fillmode","saveonexit","maxSnap"]: + elif param in ["selectBaseObjects","alwaysSnap","grid","fillmode","saveonexit","maxSnap", + "SvgLinesBlack","dxfStdSize"]: return "bool" elif param in ["color","constructioncolor","snapcolor"]: return "unsigned" @@ -782,7 +783,6 @@ def rotate(objectslist,angle,center=Vector(0,0,0),axis=Vector(0,0,1),copy=False) if len(newobjlist) == 1: return newobjlist[0] return newobjlist - def scale(objectslist,delta=Vector(1,1,1),center=Vector(0,0,0),copy=False,legacy=False): '''scale(objects,vector,[center,copy,legacy]): Scales the objects contained in objects (that can be a list of objects or an object) of the given scale @@ -1024,13 +1024,6 @@ def draftify(objectslist,makeblock=False): return newobjlist[0] return newobjlist -def getrgb(color): - "getRGB(color): returns a rgb value #000000 from a freecad color" - r = str(hex(int(color[0]*255)))[2:].zfill(2) - g = str(hex(int(color[1]*255)))[2:].zfill(2) - b = str(hex(int(color[2]*255)))[2:].zfill(2) - return "#"+r+g+b - def getSVG(obj,modifier=100,textmodifier=100,linestyle="continuous",fillstyle="shape color",direction=None): '''getSVG(object,[modifier],[textmodifier],[linestyle],[fillstyle],[direction]): returns a string containing a SVG representation of the given object. the modifier attribute @@ -1052,6 +1045,18 @@ def getSVG(obj,modifier=100,textmodifier=100,linestyle="continuous",fillstyle="s plane = WorkingPlane.plane() plane.alignToPointAndAxis(Vector(0,0,0),fcvec.neg(direction),0) + def getrgb(color): + "getRGB(color): returns a rgb value #000000 from a freecad color" + r = str(hex(int(color[0]*255)))[2:].zfill(2) + g = str(hex(int(color[1]*255)))[2:].zfill(2) + b = str(hex(int(color[2]*255)))[2:].zfill(2) + col = "#"+r+g+b + if col == "#ffffff": + print getParam('SvgLinesBlack') + if getParam('SvgLinesBlack'): + col = "#000000" + return col + def getProj(vec): if not plane: return vec nx = fcvec.project(vec,plane.u) @@ -1077,10 +1082,19 @@ def getSVG(obj,modifier=100,textmodifier=100,linestyle="continuous",fillstyle="s v = getProj(e.Vertexes[-1].Point) svg += 'L '+ str(v.x) +' '+ str(v.y) + ' ' elif isinstance(e.Curve,Part.Circle): + if len(e.Vertexes) == 1: + # complete circle + svg = getCircle(e) + return svg r = e.Curve.Radius + drawing_plane_normal = FreeCAD.DraftWorkingPlane.axis + if plane: drawing_plane_normal = plane.axis + flag_large_arc = (((e.ParameterRange[1] - e.ParameterRange[0]) / math.pi) % 2) > 1 + flag_sweep = e.Curve.Axis * drawing_plane_normal >= 0 v = getProj(e.Vertexes[-1].Point) - svg += 'A '+ str(r) + ' '+ str(r) +' 0 0 1 '+ str(v.x) +' ' - svg += str(v.y) + ' ' + svg += 'A ' + str(r) + ' ' + str(r) + ' ' + svg += '0 ' + str(int(flag_large_arc)) + ' ' + str(int(flag_sweep)) + ' ' + svg += str(v.x) + ' ' + str(v.y) + ' ' if fill != 'none': svg += 'Z' svg += '" ' svg += 'stroke="' + stroke + '" ' @@ -1092,6 +1106,21 @@ def getSVG(obj,modifier=100,textmodifier=100,linestyle="continuous",fillstyle="s svg += '/>\n' return svg + def getCircle(edge): + cen = getProj(edge.Curve.Center) + rad = edge.Curve.Radius + svg = ' + + + + + + If this is checked, imported texts will get the standard Draft text size, instead of the size they have in the DXF document + + + Use standard font size for texts + + + dxfStdSize + + + Mod/Draft + + + + + @@ -393,6 +413,29 @@ If color mapping is choosed, you must choose a color mapping file containing a t + + + + + + When exporting SVG views, make all white linework appear in black, for better readability against white backgrounds + + + Translate white line color to black + + + true + + + SvgLinesBlack + + + Mod/Draft + + + + + diff --git a/src/Mod/Draft/draftlibs/fcvec.py b/src/Mod/Draft/draftlibs/fcvec.py index 6ad79ab0f..0f3358cfc 100644 --- a/src/Mod/Draft/draftlibs/fcvec.py +++ b/src/Mod/Draft/draftlibs/fcvec.py @@ -161,9 +161,10 @@ def isColinear(vlist): '''isColinear(list_of_vectors): checks if vectors in given list are colinear''' typecheck ([(vlist,list)], "isColinear"); if len(vlist) < 3: return True + p = precision() first = vlist[1].sub(vlist[0]) for i in range(2,len(vlist)): - if angle(vlist[i].sub(vlist[0]),first) != 0: + if round(angle(vlist[i].sub(vlist[0]),first),p) != 0: return False return True diff --git a/src/Mod/Draft/importDXF.py b/src/Mod/Draft/importDXF.py index fa3bcade5..2ff051287 100644 --- a/src/Mod/Draft/importDXF.py +++ b/src/Mod/Draft/importDXF.py @@ -70,6 +70,29 @@ def decodeName(name): decodedName = name return decodedName +def deformat(text): + print text + "removes weird formats in texts and wipes UTF characters" + # remove ACAD string formatation + #t = re.sub('{([^!}]([^}]|\n)*)}', '', text) + t = text.strip("{}") + t = re.sub("\\\.*?;","",t) + # replace non-UTF chars + t = re.sub("ã","a",t) + t = re.sub("ç","c",t) + t = re.sub("õ","o",t) + t = re.sub("à","a",t) + t = re.sub("á","a",t) + t = re.sub("â","a",t) + t = re.sub("é","e",t) + t = re.sub("è","e",t) + t = re.sub("ê","e",t) + t = re.sub("í","i",t) + # replace degrees, diameters chars + t = re.sub('%%d','°',t) + t = re.sub('%%c','Ø',t) + return t + def locateLayer(wantedLayer): "returns layer group and creates it if needed" wantedLayerName = decodeName(wantedLayer) @@ -81,6 +104,17 @@ def locateLayer(wantedLayer): layers.append(newLayer) return newLayer +def getdimheight(style): + "returns the dimension text height from the given dimstyle" + for t in drawing.tables.data: + if t.name == 'dimstyle': + for a in t.data: + if hasattr(a,"type"): + if a.type == "dimstyle": + if rawValue(a,2) == style: + return rawValue(a,140) + return None + def calcBulge(v1,bulge,v2): ''' calculates intermediary vertex for curved segments. @@ -137,6 +171,7 @@ class fcformat: self.paramstyle = params.GetInt("dxfstyle") self.join = params.GetBool("joingeometry") self.makeBlocks = params.GetBool("groupLayers") + self.stdSize = params.GetBool("dxfStdSize") bparams = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/View") if self.paramstyle > 1: @@ -223,16 +258,19 @@ class fcformat: print table return table - def formatObject(self,obj,dxfobj,textmode=False): + def formatObject(self,obj,dxfobj=None): "applies color and linetype to objects" - if self.paramstyle == 1: - if textmode: + if self.paramstyle == 0: + if hasattr(obj.ViewObject,"TextColor"): obj.ViewObject.TextColor = (0.0,0.0,0.0) + elif self.paramstyle == 1: + if hasattr(obj.ViewObject,"TextColor"): + obj.ViewObject.TextColor = self.col else: obj.ViewObject.LineColor = self.col obj.ViewObject.LineWidth = self.lw - elif self.paramstyle == 2: - if textmode: + elif (self.paramstyle == 2) and dxfobj: + if hasattr(obj.ViewObject,"TextColor"): if dxfobj.color_index == 256: cm = self.getGroupColor(dxfobj)[:3] else: cm = dxfColorMap.color_map[dxfobj.color_index] obj.ViewObject.TextColor = (cm[0],cm[1],cm[2]) @@ -242,8 +280,8 @@ class fcformat: else: cm = dxfColorMap.color_map[dxfobj.color_index] obj.ViewObject.LineColor = (cm[0],cm[1],cm[2],0.0) obj.ViewObject.LineWidth = self.lw - elif self.paramstyle == 3: - if textmode: + elif (self.paramstyle == 3) and dxfobj: + if hasattr(obj.ViewObject,"TextColor"): cm = table[dxfobj.color_index][0] wm = table[dxfobj.color_index][1] obj.ViewObject.TextColor = (cm[0],cm[1],cm[2]) @@ -290,7 +328,7 @@ def drawLine(line,shapemode=False): warn(line) return None -def drawPolyline(polyline,shapemode=False): +def drawPolyline(polyline,shapemode=False,num=None): "returns a Part shape from a dxf polyline" if (len(polyline.points) > 1): edges = [] @@ -308,13 +346,13 @@ def drawPolyline(polyline,shapemode=False): cv = calcBulge(v1,polyline.points[p].bulge,v2) if fcvec.isColinear([v1,cv,v2]): try: edges.append(Part.Line(v1,v2).toShape()) - except: warn(polyline) + except: warn(polyline,num) else: try: edges.append(Part.Arc(v1,cv,v2).toShape()) - except: warn(polyline) + except: warn(polyline,num) else: try: edges.append(Part.Line(v1,v2).toShape()) - except: warn(polyline) + except: warn(polyline,num) verts.append(v2) if polyline.closed: p1 = polyline.points[len(polyline.points)-1] @@ -324,11 +362,15 @@ def drawPolyline(polyline,shapemode=False): cv = calcBulge(v1,polyline.points[-1].bulge,v2) if not fcvec.equals(v1,v2): if fcvec.isColinear([v1,cv,v2]): - try: edges.append(Part.Line(v1,v2).toShape()) - except: warn(polyline) + try: + edges.append(Part.Line(v1,v2).toShape()) + except: + warn(polyline,num) else: - try: edges.append(Part.Arc(v1,cv,v2).toShape()) - except: warn(polyline) + try: + edges.append(Part.Arc(v1,cv,v2).toShape()) + except: + warn(polyline,num) if edges: try: if (fmt.paramstyle >= 4) and (not curves) and (not shapemode): @@ -342,7 +384,7 @@ def drawPolyline(polyline,shapemode=False): else: return Part.Wire(edges) except: - warn(polyline) + warn(polyline,num) return None def drawArc(arc,shapemode=False): @@ -495,7 +537,7 @@ def drawSpline(spline,shapemode=False): return ob else: sp = Part.BSplineCurve() - print knots + # print knots sp.interpolate(verts) sh = Part.Wire(sp.toShape()) if closed: @@ -506,8 +548,11 @@ def drawSpline(spline,shapemode=False): warn(spline) return None -def drawBlock(blockref): +def drawBlock(blockref,num=None): "returns a shape from a dxf block reference" + if not fmt.paramstarblocks: + if blockref.name[0] == '*': + return None shapes = [] for line in blockref.entities.get_type('line'): s = drawLine(line,shapemode=True) @@ -525,8 +570,10 @@ def drawBlock(blockref): s = drawCircle(circle,shapemode=True) if s: shapes.append(s) for insert in blockref.entities.get_type('insert'): - s = drawInsert(insert) - if s: shapes.append(s) + print "insert ",insert," in block ",insert.block[0] + if fmt.paramstarblocks or insert.block[0] != '*': + s = drawInsert(insert) + if s: shapes.append(s) for solid in blockref.entities.get_type('solid'): s = drawSolid(solid) if s: shapes.append(s) @@ -534,11 +581,14 @@ def drawBlock(blockref): s = drawSpline(spline,shapemode=True) if s: shapes.append(s) for text in blockref.entities.get_type('text'): - if fmt.dxflayout or (not rawValue(text,67)): - addText(text) + if fmt.paramtext: + if fmt.dxflayout or (not rawValue(text,67)): + addText(text) for text in blockref.entities.get_type('mtext'): - if fmt.dxflayout or (not rawValue(text,67)): - addText(text) + if fmt.paramtext: + if fmt.dxflayout or (not rawValue(text,67)): + print "adding block text",text.value, " from ",blockref + addText(text) try: shape = Part.makeCompound(shapes) except: warn(blockref) if shape: @@ -546,14 +596,14 @@ def drawBlock(blockref): return shape return None -def drawInsert(insert): +def drawInsert(insert,num=None): if blockshapes.has_key(insert): shape = blockshapes[insert.block] else: shape = None for b in drawing.blocks.data: if b.name == insert.block: - shape = drawBlock(b) + shape = drawBlock(b,num) if fmt.paramtext: attrs = attribs(insert) for a in attrs: @@ -598,7 +648,6 @@ def attribs(insert): j = index+1 while True: ent = drawing.entities.data[j] - print str(ent) if str(ent) == 'seqend': return atts elif str(ent) == 'attrib': @@ -615,6 +664,7 @@ def addObject(shape,name="Shape",layer=None): if layer: lay=locateLayer(layer) lay.addObject(newob) + fmt.formatObject(newob) return newob def addText(text,attrib=False): @@ -630,18 +680,27 @@ def addText(text,attrib=False): pos = FreeCAD.Vector(text.loc[0],text.loc[1],text.loc[2]) hgt = text.height if val: - newob=doc.addObject("App::Annotation","Text") + if attrib: + newob = doc.addObject("App::Annotation","Attribute") + else: + newob = doc.addObject("App::Annotation","Text") lay.addObject(newob) - val = re.sub('{([^!}]([^}]|\n)*)}', '', val) - val = re.sub('%%d','°',val) - val = re.sub('%%c','Ø',val) - val = val.decode("Latin1").encode("Latin1") + val = deformat(val) + #val = val.decode("Latin1").encode("Latin1") newob.LabelText = val newob.Position = pos if gui: - newob.ViewObject.FontSize=float(hgt) + if fmt.stdSize: + newob.ViewObject.FontSize = FreeCADGui.draftToolBar.fontsize + else: + newob.ViewObject.FontSize = float(hgt) + if hasattr(text,"alignment"): + if text.alignment in [2,5,8]: + newob.ViewObject.Justification = "Center" + elif text.alignment in [3,6,9]: + newob.ViewObject.Justification = "Right" newob.ViewObject.DisplayMode = "World" - fmt.formatObject(newob,text,textmode=True) + fmt.formatObject(newob,text) def addToBlock(obj,layer): "adds given shape to the layer dict" @@ -715,10 +774,12 @@ def processdxf(document,filename): polylines.append(p) else: polylines.append(p) - if polylines: FreeCAD.Console.PrintMessage("drawing "+str(len(polylines))+" polylines...\n") + if polylines: + FreeCAD.Console.PrintMessage("drawing "+str(len(polylines))+" polylines...\n") + num = 0 for polyline in polylines: if fmt.dxflayout or (not rawValue(polyline,67)): - shape = drawPolyline(polyline) + shape = drawPolyline(polyline,num) if shape: if fmt.paramstyle == 5: if isinstance(shape,Part.Shape): @@ -743,6 +804,7 @@ def processdxf(document,filename): else: newob = addObject(shape,"Polyline",polyline.layer) if gui: fmt.formatObject(newob,polyline) + num += 1 # drawing arcs @@ -841,7 +903,8 @@ def processdxf(document,filename): if fmt.paramtext: texts = drawing.entities.get_type("mtext") texts.extend(drawing.entities.get_type("text")) - if texts: FreeCAD.Console.PrintMessage("drawing "+str(len(texts))+" texts...\n") + if texts: + FreeCAD.Console.PrintMessage("drawing "+str(len(texts))+" texts...\n") for text in texts: if fmt.dxflayout or (not rawValue(text,67)): addText(text) @@ -914,11 +977,63 @@ def processdxf(document,filename): dim.layer = layer dim.color_index = 256 fmt.formatObject (newob,dim) + if fmt.stdSize: + newob.ViewObject.FontSize = FreeCADGui.draftToolBar.fontsize + else: + st = rawValue(dim,3) + newob.ViewObject.FontSize = float(getdimheight(st)) else: FreeCAD.Console.PrintMessage("skipping dimensions...\n") - # drawing blocks + # drawing points + points = drawing.entities.get_type("point") + if points: FreeCAD.Console.PrintMessage("drawing "+str(len(points))+" points...\n") + for point in points: + x = rawValue(point,10) + y = rawValue(point,20) + z = rawValue(point,30) + lay = rawValue(point,8) + if fmt.dxflayout or (not rawValue(point,67)): + if fmt.makeBlocks: + shape = Part.Vertex(x,y,z) + addToBlock(shape,lay) + else: + newob = Draft.makePoint(x,y,z) + lay = locateLayer(lay) + lay.addObject(newob) + if gui: + fmt.formatObject(newob,point) + + # drawing leaders + + if fmt.paramtext: + leaders = drawing.entities.get_type("leader") + if leaders: + FreeCAD.Console.PrintMessage("drawing "+str(len(leaders))+" leaders...\n") + for leader in leaders: + if fmt.dxflayout or (not rawValue(leader,67)): + pts = [] + for d in leader.data: + if d[0] == 10: + pts.append([d[1]]) + elif d[0] in [20,30]: + pts[-1].append(d[1]) + pts.reverse() + points = [] + for p in pts: + points.append(Vector(p[0],p[1],p[2])) + newob = Draft.makeWire(points) + lay = locateLayer(rawValue(leader,8)) + lay.addObject(newob) + if gui: + newob.ViewObject.EndArrow = True + fmt.formatObject(newob,leader) + else: + FreeCAD.Console.PrintMessage("skipping leaders...\n") + + # drawing blocks + inserts = drawing.entities.get_type("insert") if not fmt.paramstarblocks: FreeCAD.Console.PrintMessage("skipping *blocks...\n") @@ -933,18 +1048,21 @@ def processdxf(document,filename): blockrefs = drawing.blocks.data for ref in blockrefs: drawBlock(ref) + num = 0 for insert in inserts: - shape = drawInsert(insert) + shape = drawInsert(insert,num) if shape: if fmt.makeBlocks: - addToBlock(shape,block.layer) + addToBlock(shape,insert.layer) else: newob = addObject(shape,"Block."+insert.block,insert.layer) if gui: fmt.formatObject(newob,insert) + num += 1 # make blocks, if any if fmt.makeBlocks: + print "creating layerblocks..." for k,l in layerBlocks.iteritems(): shape = drawLayerBlock(l) if shape: @@ -953,6 +1071,8 @@ def processdxf(document,filename): # finishing + print "done processing" + doc.recompute() FreeCAD.Console.PrintMessage("successfully imported "+filename+"\n") if badobjects: print "dxf: ",len(badobjects)," objects were not imported" @@ -960,9 +1080,9 @@ def processdxf(document,filename): del doc del blockshapes -def warn(dxfobject): +def warn(dxfobject,num=None): "outputs a warning if a dxf object couldn't be imported" - print "dxf: couldn't import ", dxfobject + print "dxf: couldn't import ", dxfobject, " (",num,")" badobjects.append(dxfobject) def open(filename): diff --git a/src/Mod/Draft/importSVG.py b/src/Mod/Draft/importSVG.py index 71e0103ce..067c734d5 100644 --- a/src/Mod/Draft/importSVG.py +++ b/src/Mod/Draft/importSVG.py @@ -216,19 +216,10 @@ def getcolor(color): b = float(v[2]/255.0) return (r,g,b,0.0) -def getsize(width): - "extracts a number from the given string (removes suffixes)" - if width[-1] == "%": - return float(width[:-1]) - elif len(width) > 1: - for s in ['pt','pc','mm','cm','in','px']: - if width[-2:] == s: - return float(width[:-2]) - try: - s = float(width) - return s - except ValueError: - return width +def getsize(length): + """extracts a number from the given string (removes unit suffixes)""" + number, exponent, unit=re.findall('([-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?)(px|pt|pc|mm|cm|in|em|ex|%)?',length)[0] + return float(number) def makewire(path,checkclosed=False,donttry=False): '''try to make a wire out of the list of edges. If the 'Wire' functions fails or the wire is not diff --git a/src/Mod/Drawing/App/CMakeLists.txt b/src/Mod/Drawing/App/CMakeLists.txt index 18503a274..3258959f8 100644 --- a/src/Mod/Drawing/App/CMakeLists.txt +++ b/src/Mod/Drawing/App/CMakeLists.txt @@ -69,9 +69,21 @@ ENDIF(MSVC) add_library(Drawing SHARED ${Drawing_SRCS} ${Features_SRCS} ${DrawingAlgos_SRCS}) target_link_libraries(Drawing ${Drawing_LIBS}) -fc_copy_script("Mod/Drawing" "Drawing" Init.py) -fc_copy_script("Mod/Drawing" "Drawing" DrawingAlgos.py) -fc_copy_script("Mod/Drawing" "Drawing" ${Drawing_Templates}) + +SET(Drawing_Scripts + Init.py + DrawingAlgos.py +) + +fc_target_copy_resource(Drawing + ${CMAKE_SOURCE_DIR}/src/Mod/Drawing + ${CMAKE_BINARY_DIR}/Mod/Drawing + ${Drawing_Scripts}) + +fc_target_copy_resource(Drawing + ${CMAKE_SOURCE_DIR}/src/Mod/Drawing + ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_DATADIR}/Mod/Drawing + ${Drawing_Templates}) if(MSVC) set_target_properties(Drawing PROPERTIES SUFFIX ".pyd") diff --git a/src/Mod/Drawing/CMakeLists.txt b/src/Mod/Drawing/CMakeLists.txt index 449046bd5..23d46b5fa 100644 --- a/src/Mod/Drawing/CMakeLists.txt +++ b/src/Mod/Drawing/CMakeLists.txt @@ -8,6 +8,17 @@ INSTALL( FILES Init.py InitGui.py + DrawingAlgos.py + DrawingExample.py + DrawingTests.py DESTINATION Mod/Drawing ) + +INSTALL( + DIRECTORY + Templates + DESTINATION + ${CMAKE_INSTALL_DATADIR}/Mod/Drawing + FILES_MATCHING PATTERN "*.svg*" +) diff --git a/src/Mod/Drawing/Gui/CMakeLists.txt b/src/Mod/Drawing/Gui/CMakeLists.txt index 1f5326fa4..0cb04658c 100644 --- a/src/Mod/Drawing/Gui/CMakeLists.txt +++ b/src/Mod/Drawing/Gui/CMakeLists.txt @@ -88,7 +88,12 @@ endif(MSVC) add_library(DrawingGui SHARED ${DrawingGui_SRCS} ${DrawingGuiView_SRCS} ${DrawingGuiViewProvider_SRCS}) target_link_libraries(DrawingGui ${DrawingGui_LIBS}) -fc_copy_script("Mod/Drawing" "DrawingGui" InitGui.py) + + +fc_target_copy_resource(DrawingGui + ${CMAKE_SOURCE_DIR}/src/Mod/Drawing + ${CMAKE_BINARY_DIR}/Mod/Drawing + InitGui.py) if(MSVC) set_target_properties(DrawingGui PROPERTIES SUFFIX ".pyd") diff --git a/src/Mod/Drawing/Gui/TaskOrthoViews.cpp b/src/Mod/Drawing/Gui/TaskOrthoViews.cpp index 055244a6a..b6569af36 100644 --- a/src/Mod/Drawing/Gui/TaskOrthoViews.cpp +++ b/src/Mod/Drawing/Gui/TaskOrthoViews.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (c) 2011 Joe Dowsett * + * Copyright (c) 2012 Joe Dowsett * * * * This file is part of the FreeCAD CAx development system. * * * @@ -38,37 +38,25 @@ #include #include -#include #include using namespace Gui; using namespace DrawingGui; using namespace std; - -#if 0 // needed for Qt's lupdate utility - qApp->translate("QObject", "Front"); - qApp->translate("QObject", "Back"); - qApp->translate("QObject", "Right"); - qApp->translate("QObject", "Left"); - qApp->translate("QObject", "Top"); - qApp->translate("QObject", "Bottom"); -#endif -int name_to_number(const QString& nme) -{ - char * temp[] = {"","Front","Back","Right","Left","Top","Bottom"}; - for (int j=0; j < 7; j++) - { - if (QObject::tr(temp[j]) == nme) - return j; - } - return 0; -} +#if 0 // needed for Qt's lupdate utility + qApp->translate("QObject", "Front"); + qApp->translate("QObject", "Back"); + qApp->translate("QObject", "Right"); + qApp->translate("QObject", "Left"); + qApp->translate("QObject", "Top"); + qApp->translate("QObject", "Bottom"); +#endif QString number_to_name(int j) { - char * temp[] = {"","Front","Back","Right","Left","Top","Bottom"}; + char * temp[] = {"Front","Right","Back","Left","Top","Bottom"}; QString translated = QObject::tr(temp[j]); return translated; } @@ -89,6 +77,22 @@ void rotate_coords(float& x, float& y, int i) y = t2; } +void rotate_coords(int& x, int& y, int i) +{ + int temp[4][2] = + { + { x, y}, + {-y, x}, + {-x,-y}, + { y,-x} + }; + + int t1 = temp[i][0]; + int t2 = temp[i][1]; + x = t1; + y = t2; +} + @@ -106,23 +110,28 @@ orthoView::orthoView(std::string name, const char * targetpage, const char * sou y = 0; dir = 0; angle = 0; + active = true; Command::doCommand(Command::Doc,"App.activeDocument().addObject('Drawing::FeatureViewPart','%s')",myname.c_str()); Command::doCommand(Command::Doc,"App.activeDocument().%s.Source = App.activeDocument().%s",myname.c_str(), sourcepart); Command::doCommand(Command::Doc,"App.activeDocument().%s.addObject(App.activeDocument().%s)",targetpage,myname.c_str()); + Command::doCommand(Command::Doc,"App.activeDocument().%s.Direction = (1,0,0)",myname.c_str()); activate(false); } + orthoView::~orthoView() { } + void orthoView::deleteme() { - Command::doCommand(Command::Doc,"App.activeDocument().removeObject('%s')", myname.c_str()); + Command::doCommand(Command::Doc,"App.activeDocument().removeObject('%s')", myname.c_str()); } + void orthoView::activate(bool state) { if (state) @@ -145,12 +154,13 @@ void orthoView::activate(bool state) } } + void orthoView::setDir(int i) { dir = i; - int vx = (dir == 3) - (dir == 4); - int vy = (dir == 1) - (dir == 2); - int vz = (dir == 5) - (dir == 6); + int vx = (dir == 1) - (dir == 3); + int vy = (dir == 0) - (dir == 2); + int vz = (dir == 4) - (dir == 5); //drawings default to funny orientations for each view, line below calculates rotation to correct this //drawing will then be oriented correctly for it being primary view, setOrientation is used to modify this for secondary views. @@ -165,6 +175,7 @@ void orthoView::setDir(int i) } } + void orthoView::setPos(float px, float py) { if (px != 0 && py !=0) @@ -183,6 +194,7 @@ void orthoView::setPos(float px, float py) } } + void orthoView::setScale(float newScale) { scale = newScale; @@ -190,7 +202,8 @@ void orthoView::setScale(float newScale) Command::doCommand(Command::Doc,"App.activeDocument().%s.Scale = %f",myname.c_str(), scale); calcCentre(); } - + + void orthoView::setOrientation(int orient) { orientation = orient; @@ -198,7 +211,8 @@ void orthoView::setOrientation(int orient) Command::doCommand(Command::Doc,"App.activeDocument().%s.Rotation = %d", myname.c_str(), (90*orientation+angle)); calcCentre(); } - + + void orthoView::calcCentre() { //the drawing view 'Position' refers to where the part origin should be on the page @@ -212,12 +226,11 @@ void orthoView::calcCentre() float cy = mybox.CalcCenter().y; float cz = mybox.CalcCenter().z; - float coords[7][2] = + float coords[6][2] = { - {0, 0}, {-cx, cz}, //front - { cx, cz}, //back - { cy, cz}, //right + { cy, cz}, //right + { cx, cz}, //back {-cy, cz}, //left {-cx, -cy}, //top {-cx, cy} //bottom @@ -231,16 +244,18 @@ void orthoView::calcCentre() float dy = mybox.LengthY(); float dz = mybox.LengthZ(); - float dims[4][2] = + float dims[6][2] = { - { 0, 0}, //zero height/width for no direction - {dx, dz}, //front & back - {dy, dz}, //right & left - {dx, dy} //top & bottom + {dx, dz}, //front + {dy, dz}, //right + {dx, dz}, //back + {dy, dz}, //left + {dx, dy}, //top + {dx, dy} //bottom }; - width = dims[(dir+1)/2][0]; - height = dims[(dir+1)/2][1]; + width = dims[dir][0]; + height = dims[dir][1]; if (orientation % 2 == 1) { float temp = width; @@ -249,6 +264,7 @@ void orthoView::calcCentre() } } + void orthoView::hidden(int state) { if (state == 2) @@ -257,6 +273,7 @@ void orthoView::hidden(int state) Command::doCommand(Command::Doc,"App.activeDocument().%s.ShowHiddenLines = False", myname.c_str()); } + void orthoView::smooth(int state) { if (state == 2) @@ -281,7 +298,7 @@ TaskOrthoViews::TaskOrthoViews(QWidget *parent) bbox.Add(static_cast(*it)->Shape.getBoundingBox()); const char * part = obj.front()->getNameInDocument(); - App::Document* doc = App::GetApplication().getActiveDocument(); + App::Document* doc = App::GetApplication().getActiveDocument(); std::vector pages = doc->getObjectsOfType(Drawing::FeaturePage::getClassTypeId()); std::string PageName = pages.front()->getNameInDocument(); @@ -296,74 +313,120 @@ TaskOrthoViews::TaskOrthoViews(QWidget *parent) views[1] = new orthoView(name1, page, part, bbox); name1 = doc->getUniqueObjectName("Ortho").c_str(); views[2] = new orthoView(name1, page, part, bbox); - - primary = 0; - secondary_1 = 0; - secondary_2 = 0; - rotate = 0; - proj = 1; - autoscale = 1; + name1 = doc->getUniqueObjectName("Ortho").c_str(); + views[3] = new orthoView(name1, page, part, bbox); margin = 10; pagesize(template_name); min_space = 15; - //below are calculated in case autodims is deselected before these values are initialised. - float max_dim = max(max(bbox.LengthX(), bbox.LengthY()), bbox.LengthZ()); - scale = min(pagewidth, pageh2)/(3*max_dim+4*min_space); - spacing_1 = scale*max_dim + min_space; - spacing_2 = spacing_1; - x_pos = pagewidth/2; - y_pos = pageh1/2; + // [x+2][y+2] + c_boxes[0][2] = ui->cb02; //left most, x = -2, y = 0 + c_boxes[1][1] = ui->cb11; + c_boxes[1][2] = ui->cb12; + c_boxes[1][3] = ui->cb13; + c_boxes[2][0] = ui->cb20; //top most, x = 0, y = -2 + c_boxes[2][1] = ui->cb21; + c_boxes[2][2] = ui->cb22; //centre (primary view) checkbox x = y = 0. + c_boxes[2][3] = ui->cb23; + c_boxes[2][4] = ui->cb24; //bottom most, x = 0, y = 2 + c_boxes[3][1] = ui->cb31; + c_boxes[3][2] = ui->cb32; + c_boxes[3][3] = ui->cb33; + c_boxes[4][2] = ui->cb42; //right most, x = 2, y = 0 + for (int i=0; i < 5; i++) + for (int j=0; j < 5; j++) + if ((abs(i-2) + abs(j-2)) < 3) //if i,j combination corresponds to valid check box, then proceed with: + connect(c_boxes[i][j], SIGNAL(toggled(bool)), this, SLOT(cb_toggled(bool))); + + inputs[0] = ui->scale_0; + inputs[1] = ui->x_1; + inputs[2] = ui->y_2; + inputs[3] = ui->spacing_h_3; + inputs[4] = ui->spacing_v_4; + + for (int i=0; i < 5; i++) + connect(inputs[i], SIGNAL(editingFinished()), this, SLOT(data_entered())); connect(ui->projection, SIGNAL(currentIndexChanged(int)), this, SLOT(projectionChanged(int))); connect(ui->rotate, SIGNAL(currentIndexChanged(int)), this, SLOT(setRotate(int))); connect(ui->smooth, SIGNAL(stateChanged(int)), this, SLOT(smooth(int))); connect(ui->hidden, SIGNAL(stateChanged(int)), this, SLOT(hidden(int))); connect(ui->auto_tog, SIGNAL(stateChanged(int)), this, SLOT(toggle_auto(int))); - connect(ui->spacing1, SIGNAL(editingFinished()), this, SLOT(data_entered())); - connect(ui->spacing2, SIGNAL(editingFinished()), this, SLOT(data_entered())); - connect(ui->x, SIGNAL(editingFinished()), this, SLOT(data_entered())); - connect(ui->y, SIGNAL(editingFinished()), this, SLOT(data_entered())); - connect(ui->scale, SIGNAL(editingFinished()), this, SLOT(data_entered())); connect(ui->primary, SIGNAL(activated(int)), this, SLOT(setPrimary(int))); - connect(ui->secondary_1, SIGNAL(activated(int)), this, SLOT(setSecondary_1(int))); - connect(ui->secondary_2, SIGNAL(activated(int)), this, SLOT(setSecondary_2(int))); - -//this matrix contains the relative positions of specified views in third angle projection. -//horizontal coord specifies the primary view, vertical coord specifies a secondary view -//but to retrieve, get transfrom[secondary][primary] -//then matrix contents {x,y,r} specifies directional x and y of secondary view relative to primary view (with y increasing downwards as per SVG -//r specifies rotation of view from default, eg 1 = 90 degrees clockwise. -// -//first angle can be obtained by taking -ve of x and y coords, no change of r is required. - // primary view direction -> 1 2 3 4 5 6 - int temp[7][7][3] ={{{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, - /*secondary 1 */ {{0,0,0}, {0,0,0}, {0,0,0}, {-1,0,0}, {1,0,0}, {0,1,0}, {0,-1,0}}, - /*view 2 */ {{0,0,0}, {0,0,0}, {0,0,0}, {1,0,0}, {-1,0,0}, {0,-1,2}, {0,1,2}}, - /*direction 3 */ {{0,0,0}, {1,0,0}, {-1,0,0}, {0,0,0}, {0,0,0}, {1,0,3}, {1,0,1}}, - /* 4 */ {{0,0,0}, {-1,0,0}, {1,0,0}, {0,0,0}, {0,0,0}, {-1,0,1}, {-1,0,3}}, - /* 5 */ {{0,0,0}, {0,-1,0}, {0,-1,2}, {0,-1,1}, {0,-1,3}, {0,0,0}, {0,0,0}}, - /* 6 */ {{0,0,0}, {0,1,0}, {0,1,2}, {0,1,3}, {0,1,1}, {0,0,0}, {0,0,0}}}; - - for (int i=0; i < 7; i++) - for (int j=0; j < 7; j++) - for (int k=0; k < 3; k++) //initialisation needs to be done this way (rather than initialise transform directly - transform[i][j][k] = temp[i][j][k]; //in order to avoid compiler warning + //these matrices contain information relating relative position on page to which view appears there, and in which orientation + + //first matrix is for front, right, back, left. Only needs to contain positions above and below primary since in positions horizontally + //displaced, the view appearing there is simply found from the same f, r, b, l sequence. + //thus [i][j][k], i values are which primary view (0-3), j is vertical displacement corresponding to (-2/+2, -1, 1) + //then in k = 0 is the view number, k = 1 is the orientation (*90 clockwise) + + //second matrix is for primaries top (4), i=0 gives horizontal positions, i = 1 vertical ones + //and bottom (5) i = 2 (horiz) and 3 (vert). + //then j and k values as for first matrix. + + int temp1[4][3][2] = {{{2,2}, {4,0}, {5,0}}, //primary 0, secondary {direction, rotation} in y = -2, -1, 1 positions + {{3,2}, {4,1}, {5,3}}, //primary 1, secondaries in y = 2 position duplicate y = -2 + {{0,2}, {4,2}, {5,2}}, //primary 2, secondaries in horizontal positions x = -2, -1, 1, 2 + {{1,2}, {4,3}, {5,1}}}; //primary 3, given by linear position from primary = (p + x) mod 4 + + int temp2[4][3][2] = {{{5,2}, {3,1}, {1,3}}, //primary 4, secondaries in horizontal x = -2, -1, 1 (x = 2 duplicates x = -2) + {{5,0}, {2,2}, {0,0}}, //primary 4, vertical positions + {{4,2}, {3,3}, {1,1}}, //primary 5, horizontal + {{4,0}, {0,0}, {2,2}}}; //primary 5, vertical + + for (int i=0; i < 4; i++) + for (int j=0; j < 3; j++) + for (int k=0; k < 2; k++) //initialisation needs to be done this way (rather than initialise maps directly + { + map1[i][j][k] = temp1[i][j][k]; //in order to avoid compiler warning + map2[i][j][k] = temp2[i][j][k]; + } + + //initialise variables + + for (int i=0; i < 4; i++) + for (int j=0; j < 4; j++) + view_status[i][j] = 0; + + view_count = 0; + primary = 0; + rotate = 0; + proj = 1; + autoscale = 1; + + //below are calculated in case autodims is deselected before these values are initialised. + float max_dim = max(max(bbox.LengthX(), bbox.LengthY()), bbox.LengthZ()); + scale = min(pagewidth, pageheight)/(4*max_dim+5*min_space); + horiz = scale*max_dim + min_space; + vert = horiz; + x_pos = pagewidth/2; + y_pos = pageheight/2; + + data[0] = &scale; + data[1] = &x_pos; + data[2] = &y_pos; + data[3] = &horiz; + data[4] = | + + +// Command::doCommand(Command::Doc,"#%d", map1[2][2][1]); -// Command::doCommand(Command::Doc,"#%d", transform[6][3][2]); } //end of constructor + TaskOrthoViews::~TaskOrthoViews() { delete views[0]; delete views[1]; delete views[2]; + delete views[3]; delete ui; } + void TaskOrthoViews::changeEvent(QEvent *e) { if (e->type() == QEvent::LanguageChange) { @@ -375,24 +438,24 @@ void TaskOrthoViews::changeEvent(QEvent *e) void TaskOrthoViews::pagesize(std::string& page_template) { /********update num_templates when adding extra templates*******************/ - + const int num_templates = 2; std::string templates[num_templates] = {"A3_Landscape.svg", "A4_Landscape.svg"}; int dimensions[num_templates][3] = {{420,297,227},{297,210,153}}; //{width, full height, reduced height} measured from page edge. - + for (int i=0; i < num_templates; i++) - { + { if (templates[i] == page_template) { pagewidth = dimensions[i][0] - 2*margin; pageh1 = dimensions[i][1] - 2*margin; - pageh2 = dimensions[i][2] - ((dimensions[i][1] == dimensions[i][2]) + 1) * margin; + pageh2 = dimensions[i][2] - margin; return; } } - + //matching template not found, read through template file for width & height info. - + //code below copied from FeaturePage.cpp Base::FileInfo fi(page_template); if (!fi.isReadable()) { @@ -412,7 +475,7 @@ void TaskOrthoViews::pagesize(std::string& page_template) std::ifstream file (fi.filePath().c_str()); size_t found; bool done = false; - + try { while (!file.eof()) @@ -422,11 +485,9 @@ void TaskOrthoViews::pagesize(std::string& page_template) if (found != std::string::npos) { temp_line = line.substr(7+found); - found = temp_line.find("\""); - temp_line = temp_line.substr(0,found); - std::stringstream num_str(temp_line); - num_str >> pagewidth; + sscanf (temp_line.c_str(), "%f", &pagewidth); pagewidth -= 2*margin; + if (done) { file.close(); @@ -435,17 +496,15 @@ void TaskOrthoViews::pagesize(std::string& page_template) else done = true; } - + found = line.find("height="); if (found != std::string::npos) { temp_line = line.substr(8+found); - found = temp_line.find("\""); - temp_line = temp_line.substr(0,found); - std::stringstream num_str_2(temp_line); - num_str_2 >> pageh1; + sscanf (temp_line.c_str(), "%f", &pageh1); pageh1 -= 2*margin; pageh2 = pageh1; + if (done) { file.close(); @@ -454,15 +513,15 @@ void TaskOrthoViews::pagesize(std::string& page_template) else done = true; } - + if (line.find("metadata") != std::string::npos) //give up if we meet a metadata tag break; } } catch (Standard_Failure) { } - - file.close(); - + + file.close(); + //width/height not found?? fallback to A4 landscape simple: pagewidth = 277; pageh1 = 190; @@ -470,387 +529,378 @@ void TaskOrthoViews::pagesize(std::string& page_template) } -void TaskOrthoViews::autodims(float s1_x, float s1_y, float s2_x, float s2_y) +void TaskOrthoViews::autodims() { - int num_wide = abs(s1_x) + abs(s2_x) + 2; //tells us how many 'spaces' there are in each direction - int num_high = abs(s1_y) + abs(s2_y) + 2; //eg if s1_x = 1, then 3 spaces, page_edge -> primary -> secondary -> page_edge + /************************************* calculate real size of views in layout *****************/ - //now calculate real (non-scaled) width/height of views when combined togethor - float width = views[0]->width; //dimensions of primary view - float height = views[0]->height; - width += (s1_x != 0) * views[1]->width; //only add width if secondary view is alongside primary (ie s1_x <> 0) - height += (s1_y != 0) * views[1]->height; //equivalently for height - width += (s2_x != 0) * views[2]->width; - height += (s2_y != 0) * views[2]->height; + float w1 = 0, w2 = 0, h1 = 0, h2 = 0; + int min_x = 0, min_y = 0; + int max_x = 0, max_y = 0; - int pageheight; //allow extra page height if view arrangement avoids the information box on the bottom right - if (((s1_x + s1_y + s2_x + s2_y) == 2) && (views[0]->width <= width/2)) + w1 = views[0]->width; //w1,h1 are width/height of primary view + h1 = views[0]->height; //w2 width of first view left/right of primary, h2 height of first view up/down + + for (int i = 0; i < 4; i++) + { + min_x = min(min_x, view_status[i][2]); + min_y = min(min_y, view_status[i][3]); + max_x = max(max_x, view_status[i][2]); + max_y = max(max_y, view_status[i][3]); + + if (abs(view_status[i][2]) == 1 && abs(view_status[i][3]) == 0) + w2 = views[i]->width; + else if (abs(view_status[i][2]) == 0 && abs(view_status[i][3]) == 1) + h2 = views[i]->height; + } + + float width = (min_x == -2)*w1 + (min_x < 0)*w2 + w1 + (max_x > 0)*w2 + (max_x == 2) * w1; + float height = (min_y == -2)*h1 + (min_y < 0)*h2 + h1 + (max_y > 0)*h2 + (max_y == 2) * h1; + int wide = max_x - min_x + 1; //how many views wide / high? + int high = max_y - min_y + 1; + + if (max_y > 0 && !c_boxes[3][3]->isChecked() && min_x == 0 && ((max_x == 1)*w2 > w1 || max_x == 2)) pageheight = pageh1; else pageheight = pageh2; + + /*************************************** calculate scale **************************************/ - //now evaluate available space / space required for each direction, and choose the smaller. - float working_scale = min((pagewidth - num_wide * min_space) / width, (pageheight - num_high * min_space) / height); + float working_scale = min((pagewidth - (wide + 1) * min_space) / width, (pageheight - (high + 1) * min_space) / height); - //that gives the largest scale for which the min_space requirements can be met, but we want a 'sensible' scale, rather than 0.28457239! - //eg if working_scale = 0.115, then we want to use 0.1 - // if working_scale = 7.65, then we want to use 5 - // if working_scale = 76.5, then we want to use 50 - float exponent = floor(log10(working_scale)); //if working_scale = a * 10^b, what is b? - working_scale *= pow(10, -exponent); //now find what 'a' is. + //which gives the largest scale for which the min_space requirements can be met, but we want a 'sensible' scale, rather than 0.28457239... + //eg if working_scale = 0.115, then we want to use 0.1, similarly 7.65 -> 5, and 76.5 -> 50 + + float exponent = floor(log10(working_scale)); //if working_scale = a * 10^b, what is b? + working_scale *= pow(10, -exponent); //now find what 'a' is. + + float valid_scales[2][8] = {{1, 1.25, 2, 2.5, 3.75, 5, 7.5, 10}, //equate to 1:10, 1:8, 1:5, 1:4, 3:8, 1:2, 3:4, 1:1 + {1, 1.5, 2, 3, 4, 5, 8, 10}}; //equate to 1:1, 3:2, 2:1, 3:1, 4:1, 5:1, 8:1, 10:1 - float valid_scales[2][8] = {{1, 1.25, 2, 2.5, 3.75, 5, 7.5, 10}, //equate to 1:10, 1:8, 1:5, 1:4, 3:8, 1:2, 3:4, 1:1 - {1, 1.5, 2, 3, 4, 5, 8, 10}}; //equate to 1:1, 3:2, 2:1, 3:1, 4:1, 5:1, 8:1, 10:1 int i = 0; - while (valid_scales[(exponent>=0)][i] <= working_scale) //choose closest value smaller than 'a' from list. - i += 1; //choosing top list if exponent -ve, bottom list for +ve exponent + while (valid_scales[(exponent>=0)][i] <= working_scale) //choose closest value smaller than 'a' from list. + i += 1; //choosing top list if exponent -ve, bottom list for +ve exponent i -= 1; float chosen_scale = valid_scales[(exponent>=0)][i]; - scale = chosen_scale * pow(10, exponent); //now have the appropriate scale, reapply the *10^b + scale = chosen_scale * pow(10, exponent); //now have the appropriate scale, reapply the *10^b - /////////////////////// - //now we move on to the placements - width *= scale; + /************************************* calculate position of views on page ********************/ + + width *= scale; height *= scale; - - //which direction gives the smallest space between views? Space is given by (page size - size of views) / (number of spaces) - float space = min((pagewidth - width)/num_wide, (pageheight - height)/num_high); - - //now calculate the spacing of the secondary views from the primary one - //***********************spacing is currently view centre -> view centre******************************** - //so the spacing is equal to (primary centre -> prmry edge) + (secondary centre -> scdry edge) + space - //these depend upon whether secondary is vertically or horizontally primary from primary - - if (s1_x != 0) //secondary_1 is horizontally placed from primary - spacing_1 = space + scale*(views[0]->width + views[1]->width)/2; - else //secondary_1 is vertically placed from primary - spacing_1 = space + scale*(views[0]->height + views[1]->height)/2; - + w1 *= scale; + w2 *= scale; + h1 *= scale; + h2 *= scale; - if (s2_x != 0) //same for secondary_2 - spacing_2 = space + scale*(views[0]->width + views[2]->width)/2; - else - spacing_2 = space + scale*(views[0]->height + views[2]->height)/2; - - spacing_1 = floor(spacing_1*10 + 0.5) / 10; - spacing_2 = floor(spacing_2*10 + 0.5) / 10; - - /////////////////////////////////////////// - //finally, evaluate position of primary view. - - int pos_wide = s1_x + s2_x; //=1 = primary on left, 0 = primary in middle, -1 = on right - int pos_high = s1_y + s2_y; //=1 = at top, 0 = in middle, -1 = at bottom - - if (pos_wide == 1) - x_pos = (pagewidth / 2.0 + margin) - ((width + space) - scale * views[0]->width)/2; - else if (pos_wide == 0) - x_pos = pagewidth / 2.0 + margin; - else - x_pos = (pagewidth / 2.0 + margin) + ((width + space) - scale * views[0]->width)/2; + float space = min((pagewidth - width)/(wide + 1), (pageheight - height)/(high + 1)); + vert = space + (h1 + h2)/2; //centre-centre spacing of views + horiz = space + (w1 + w2)/2; - if (pos_high == 1) - y_pos = (pageheight / 2.0 + margin) - ((height + space) - scale * views[0]->height)/2; - else if (pos_high == 0) - y_pos = pageheight / 2.0 + margin; - else - y_pos = (pageheight / 2.0 + margin) + ((height + space) - scale * views[0]->height)/2; - - x_pos = floor(x_pos * 10 + 0.5) / 10; + float left = -min_x * horiz + (min_x == -1) * w2/2 + (min_x != -1) * w1/2; //width of layout left of primary centre + float right = max_x * horiz + (max_x == 1) * w2/2 + (max_x != 1) * w1/2; // " " right " " + float up = -min_y * vert + (min_y == -1) * h2/2 + (min_y != -1) * h1/2; + float down = max_y * vert + (max_y == 1) * h2/2 + (max_y != 1) * h1/2; + + x_pos = pagewidth/2 + margin - (right-left)/2; + y_pos = pageheight/2 + margin - (down-up)/2; + + x_pos = floor(x_pos * 10 + 0.5) / 10; //round to nearest tenth y_pos = floor(y_pos * 10 + 0.5) / 10; - - //////////// - //update the gui boxes with calculated information - ui->scale->setText(QString::number(scale)); - ui->x->setText(QString::number(x_pos)); - ui->y->setText(QString::number(y_pos)); - ui->spacing1->setText(QString::number(spacing_1)); - ui->spacing2->setText(QString::number(spacing_2)); + horiz = floor(horiz * 10 + 0.5) / 10; + vert = floor(vert * 10 + 0.5) / 10; + + + /************************************* update gui text boxes **********************************/ + + for (int i = 0; i < 5; i++) + inputs[i]->setText(QString::number(*data[i])); } + void TaskOrthoViews::compute() { -//secondary 1 - float s1_x = proj * transform[secondary_1][primary][0]; - float s1_y = proj * transform[secondary_1][primary][1]; - rotate_coords(s1_x,s1_y,rotate); - float s1_r = (rotate + transform[secondary_1][primary][2])%4; - -//secondary 2 - float s2_x = proj * transform[secondary_2][primary][0]; - float s2_y = proj * transform[secondary_2][primary][1]; - rotate_coords(s2_x,s2_y,rotate); - float s2_r = (rotate + transform[secondary_2][primary][2])%4; - - //autodims will retrieve information from views[] regarding image dimensions - //thus need to set views[] direction and orientation before calling autodims. - views[0]->setDir(primary); - views[0]->setOrientation(rotate); - - views[1]->setDir(secondary_1); - views[1]->setOrientation(s1_r); - - views[2]->setDir(secondary_2); - views[2]->setOrientation(s2_r); - if (autoscale) - autodims(s1_x, s1_y, s2_x, s2_y); + autodims(); - views[0]->setScale(scale); - views[0]->setPos(x_pos,y_pos); - - views[1]->setScale(scale); - views[1]->setPos(x_pos + spacing_1 * s1_x, y_pos + spacing_1 * s1_y); - - views[2]->setScale(scale); - views[2]->setPos(x_pos + spacing_2 * s2_x, y_pos + spacing_2 * s2_y); + for (int i = 0; i < 4; i++) + { + views[i]->setScale(scale); + views[i]->setPos(x_pos + view_status[i][2] * horiz, y_pos + view_status[i][3] * vert); + } Command::updateActive(); Command::commitCommand(); } - + + +void TaskOrthoViews::validate_cbs() +{ + for (int i=0; i < 5; i++) + for (int j=0; j < 5; j++) + if ((abs(i-2) + abs(j-2)) < 3) //if i,j combination corresponds to valid check box, then proceed with: + + if (view_count == 0) + { + c_boxes[i][j]->setEnabled(false); + c_boxes[i][j]->setChecked(false); + } + else if (!c_boxes[i][j]->isChecked()) //only questions boxes 'enableability' if it's not checked + if (view_count == 4) + c_boxes[i][j]->setEnabled(false); //if there are four checked boxes then all others are disabled + else + { + if ((abs(i-2) + abs(j-2)) == 1) //only true for boxes immediately up/down/left/right of centre + c_boxes[i][j]->setEnabled(c_boxes[2][2]->isChecked()); //which are enabled if centre box is checked + else + { + int di = ((i-2) < 0) - ((i-2) > 0); //which direction is towards centre? + int dj = ((j-2) < 0) - ((j-2) > 0); + + if (c_boxes[i+di][j]->isChecked() + c_boxes[i][j+dj]->isChecked() + (di == 0) + (dj == 0) == 2) + { + if (!((i == 2)*(j == 2))) //don't enable the centre one! +/********temporary if statement here, remove the following if to renable 'diagonal' checkboxes *******/ + if ((i-2) * (j-2) == 0) + c_boxes[i][j]->setEnabled(true); //if this box's inner neighbour(s) are checked, then this one enabled + } + else + c_boxes[i][j]->setEnabled(false); + } + } +} + + +void TaskOrthoViews::cb_toggled(bool toggle) +{ + QString name = sender()->objectName().right(2); + char letter = name.toStdString()[0]; + int dx = letter - '0' - 2; + + letter = name.toStdString()[1]; + int dy = letter - '0' - 2; + + int i = 0; + if (toggle) + { + for (i = 0; i < 4; i++) + { + if (view_status[i][0] == 0) + break; + } + + int direction, rotation; + view_data(dx, dy, direction, rotation); + view_status[i][0] = 1; + view_status[i][2] = dx; + view_status[i][3] = dy; + views[i]->activate(true); + views[i]->setDir(direction); + views[i]->setOrientation(rotation); + view_count += 1; + } + else + { + if (abs(dx) == 1 || abs(dy == 1)) + c_boxes[dx*2+2][dy*2+2]->setChecked(false); + + for (i = 0; i < 4; i++) + { + if (view_status[i][2] == dx && view_status[i][3] == dy) + break; + } + views[i]->activate(false); + view_status[i][0] = 0; + view_status[i][2] = 0; + view_status[i][3] = 0; + view_count -= 1; + } + validate_cbs(); + compute(); +} + + +void TaskOrthoViews::view_data(int x, int y, int & direction, int & rotation) +{ + int arr_index; + rotate_coords(x,y,(4-rotate)%4); + x = x * proj; + y = y * proj; + + if (primary < 4) + { + if (y == 0) + { + rotation = rotate; + direction = (primary + x + 4) % 4; + } + else + { + arr_index = (y + 2 - (y > 0)) % 3; //maps (-2,-1,1,2) to (0,1,2,0) + direction = map1[primary][arr_index][0]; + rotation = (map1[primary][arr_index][1] + rotate) % 4; + } + } + else + { + int offset = (y != 0); + arr_index = (x == 0)*(y + 2 - (y > 0)) % 3 + (y == 0)*(x + 2 - (x > 0)) % 3; + direction = map2[2*(primary == 5) + offset][arr_index][0]; + rotation = (map2[2*(primary == 5) + offset][arr_index][1] + rotate) % 4; + } +} + + void TaskOrthoViews::projectionChanged(int index) { proj = 2*(0.5-index); //gives -1 for 1st angle and 1 for 3rd + updateSecondaries(); compute(); } + void TaskOrthoViews::setRotate(int r) { rotate = r; + views[0]->setOrientation(rotate); + updateSecondaries(); compute(); } -void TaskOrthoViews::populate_s1() -{ - ui->secondary_1->clear(); - ui->secondary_1->addItem(QString()); - - int i = 0; - int k = 0; - for (int j=1; j < 7; j++) - if (((j+1)/2 != (primary+1)/2) && (j != secondary_2)) - { - k += 1; - ui->secondary_1->addItem(number_to_name(j)); - if (j == secondary_1) - i = k; - } - ui->secondary_1->setCurrentIndex(i); +void TaskOrthoViews::updateSecondaries() +{ + int direction, rotation; + int dx, dy; + + for (int i = 1; i < 4; i++) + if (view_status[i][0] == 1) + { + dx = view_status[i][2]; + dy = view_status[i][3]; + view_data(dx, dy, direction, rotation); + views[i]->setDir(direction); + views[i]->setOrientation(rotation); + } } -void TaskOrthoViews::populate_s2() -{ - ui->secondary_2->clear(); - ui->secondary_2->addItem(QString()); - - int i = 0; - int k = 0; - for (int j=1; j < 7; j++) - if (((j+1)/2 != (primary+1)/2) && (j != secondary_1)) - { - k += 1; - ui->secondary_2->addItem(number_to_name(j)); - if (j == secondary_2) - i = k; - } - - ui->secondary_2->setCurrentIndex(i); -} void TaskOrthoViews::setPrimary(int dir) { if (dir == 0) { - views[0]->activate(false); - views[1]->activate(false); - views[2]->activate(false); - primary = 0; - secondary_1 = 0; - secondary_2 = 0; - ui->secondary_1->setCurrentIndex(0); - ui->secondary_2->setCurrentIndex(0); + for (int i = 0; i < 4; i++) + { + views[i]->activate(false); + view_status[i][0] = 0; + } + view_count = 0; + c_boxes[2][2]->setChecked(false); } else { - if (!views[0]->active) - views[0]->activate(true); - - primary = dir; - - if ((primary+1)/2 == (secondary_1+1)/2) //eg primary = 1, secondary_1 = 2 - { - views[1]->activate(false); - secondary_1 = 0; - ui->secondary_1->setCurrentIndex(0); - } - - if ((primary+1)/2 == (secondary_2+1)/2) - { - views[2]->activate(false); - secondary_2 = 0; - ui->secondary_2->setCurrentIndex(0); - } - populate_s1(); - populate_s2(); + c_boxes[2][2]->setChecked(true); + view_count += (view_count == 0); + primary = dir-1; + view_status[0][0] = 1; + views[0]->setDir(primary); + views[0]->setOrientation(rotate); + views[0]->activate(true); + updateSecondaries(); compute(); } + validate_cbs(); } -void TaskOrthoViews::setSecondary_1(int dir) -{ - if (dir == 0) - { - views[1]->activate(false); - secondary_1 = 0; - } - else - { - QString text = ui->secondary_1->currentText(); - int value = name_to_number(text); - if (!views[1]->active) - views[1]->activate(true); - secondary_1 = value; - } - populate_s2(); - compute(); -} - -void TaskOrthoViews::setSecondary_2(int dir) -{ - if (dir == 0) - { - views[2]->activate(false); - secondary_2 = 0; - } - else - { - QString text = ui->secondary_2->currentText(); - int value = name_to_number(text); - if (!views[2]->active) - views[2]->activate(true); - secondary_2 = value; - } - populate_s1(); - compute(); -} void TaskOrthoViews::hidden(int i) { views[0]->hidden(i); views[1]->hidden(i); views[2]->hidden(i); + views[3]->hidden(i); Command::updateActive(); Command::commitCommand(); } + void TaskOrthoViews::smooth(int i) { views[0]->smooth(i); views[1]->smooth(i); views[2]->smooth(i); + views[3]->smooth(i); Command::updateActive(); Command::commitCommand(); } + void TaskOrthoViews::toggle_auto(int i) { - if (i == 2) //auto scale switched on + if (i == 2) //auto scale switched on { autoscale = true; - ui->scale->setEnabled(false); - ui->x->setEnabled(false); - ui->y->setEnabled(false); - ui->spacing1->setEnabled(false); - ui->spacing2->setEnabled(false); ui->label_4->setEnabled(false); ui->label_5->setEnabled(false); ui->label_6->setEnabled(false); + for (int j = 0; j < 5; j++) + inputs[j]->setEnabled(false); //disable user input boxes compute(); } else { autoscale = false; - ui->scale->setEnabled(true); - ui->x->setEnabled(true); - ui->y->setEnabled(true); - ui->spacing1->setEnabled(true); - ui->spacing2->setEnabled(true); - ui->label_4->setEnabled(true); - ui->label_5->setEnabled(true); - ui->label_6->setEnabled(true); + ui->label_4->setEnabled(true); + ui->label_5->setEnabled(true); + ui->label_6->setEnabled(true); + for (int j = 0; j < 5; j++) + inputs[j]->setEnabled(true); //enable user input boxes } } + void TaskOrthoViews::data_entered() { - bool ok; + Command::doCommand(Command::Doc,"#1"); + bool ok; - float value = ui->spacing1->text().toFloat(&ok); - if (ok) - spacing_1 = value; - else - { - ui->spacing1->setText(QString::number(spacing_1)); - return; - } - - value = ui->spacing2->text().toFloat(&ok); - if (ok) - spacing_2 = value; - else - { - ui->spacing2->setText(QString::number(spacing_2)); - return; - } + QString name = sender()->objectName().right(1); + char letter = name.toStdString()[0]; + int index = letter - '0'; - value = ui->x->text().toFloat(&ok); - if (ok) - x_pos = value; - else - { - ui->x->setText(QString::number(x_pos)); - return; - } - value = ui->y->text().toFloat(&ok); + float value = inputs[index]->text().toFloat(&ok); if (ok) - y_pos = value; + *data[index] = value; else { - ui->y->setText(QString::number(y_pos)); - return; - } - - value = ui->scale->text().toFloat(&ok); - if (ok) - scale = value; - else - { - ui->scale->setText(QString::number(scale)); + inputs[index]->setText(QString::number(*data[index])); return; } compute(); + Command::doCommand(Command::Doc,"#2"); } + bool TaskOrthoViews::user_input() { //if user presses return, this is intercepted by FreeCAD which interprets it as activating the 'OK' button //if return was pressed in a text box though, we don't want it to do 'OK', so check to see if a text box has been modified. - bool modified = (ui->spacing1->isModified() || ui->spacing2->isModified() || ui->x->isModified() || ui->y->isModified() || ui->scale->isModified()); + bool modified = false; - if (modified) + for (int i = 0; i < 5; i++) { - ui->spacing1->setModified(false); - ui->spacing2->setModified(false); - ui->x->setModified(false); - ui->y->setModified(false); - ui->scale->setModified(false); + modified = inputs[i]->isModified(); //has input box been modified? + if (modified) + { + inputs[i]->setModified(false); //reset modified flag + break; //stop checking + } } return modified; } + void TaskOrthoViews::clean_up(bool keep) { if (keep) //user ok-ed the drawing @@ -861,12 +911,15 @@ void TaskOrthoViews::clean_up(bool keep) views[1]->deleteme(); if (!views[2]->active) views[2]->deleteme(); + if (!views[3]->active) + views[3]->deleteme(); } else //user cancelled the drawing { views[0]->deleteme(); views[1]->deleteme(); - views[2]->deleteme(); + views[2]->deleteme(); + views[3]->deleteme(); } } @@ -892,7 +945,6 @@ TaskDlgOrthoViews::TaskDlgOrthoViews() TaskDlgOrthoViews::~TaskDlgOrthoViews() { - } //==== calls from the TaskView =============================================================== @@ -900,12 +952,10 @@ TaskDlgOrthoViews::~TaskDlgOrthoViews() void TaskDlgOrthoViews::open() { - } void TaskDlgOrthoViews::clicked(int) { - } bool TaskDlgOrthoViews::accept() diff --git a/src/Mod/Drawing/Gui/TaskOrthoViews.h b/src/Mod/Drawing/Gui/TaskOrthoViews.h index 1e97d4169..cb8dd7716 100644 --- a/src/Mod/Drawing/Gui/TaskOrthoViews.h +++ b/src/Mod/Drawing/Gui/TaskOrthoViews.h @@ -86,8 +86,7 @@ public: protected Q_SLOTS: void setPrimary(int); void setRotate(int); - void setSecondary_1(int); - void setSecondary_2(int); + void cb_toggled(bool); void projectionChanged(int); void hidden(int); void smooth(int); @@ -99,25 +98,37 @@ protected: private: void pagesize(std::string&); + void autodims(); void compute(); - void autodims(float, float, float, float); - void populate_s1(); - void populate_s2(); + void validate_cbs(); + void view_data(int, int, int &, int &); + void updateSecondaries(); private: class Private; Ui_TaskOrthoViews * ui; - orthoView * views[3]; - int transform[7][7][3]; //matrix containing relative positions and rotations of secondary views depending upon primary view + orthoView * views[4]; + QCheckBox * c_boxes[5][5]; //matrix of pointers to gui checkboxes + QLineEdit * inputs[5]; //pointers to manual position/scale boxes + float * data[5]; //pointers to scale, x_pos, y_pos, horiz, vert + + int map1[4][3][2]; //contains view directions and rotations for vertical secondary positions, for primaries 1,2,3,4 + int map2[4][3][2]; //contains view directions and rotations for H and V secondary positions, primaries 5,6 + + int view_status[4][4]; //matrix containing status of four orthoView objects (in use, axo, rel x, rel y) + int view_count; //number of active views + int primary; //view direction of primary view - int secondary_1, secondary_2; //view direction of secondary views - int spacing_1, spacing_2; //spacings of secondary view centre from primary view centre float x_pos, y_pos; //x and y coords for primary view int rotate; //rotate primary view clockwise by rotate*90 int proj; //first (=-1) or third (=1) angle projection float scale; //scale of drawing bool autoscale; //whether or not to run autodims - int pagewidth, pageh1, pageh2; //these are actually the available width and height, calculated in constructor. + + float horiz, vert; //centre-centre distances + + float pagewidth, pageheight; //these are actually the available width and height, calculated in constructor. + float pageh1, pageh2; //h1 - total usable page height, h2 - total height allowing for info box. int margin; int min_space; //minimum space between views, and page edge }; diff --git a/src/Mod/Drawing/Gui/TaskOrthoViews.ui b/src/Mod/Drawing/Gui/TaskOrthoViews.ui index 78e6cc2ca..2ecb40cf2 100644 --- a/src/Mod/Drawing/Gui/TaskOrthoViews.ui +++ b/src/Mod/Drawing/Gui/TaskOrthoViews.ui @@ -6,21 +6,30 @@ 0 0 - 272 - 394 + 250 + 491 - + 0 0 + + + 250 + 0 + + Orthographic Projection - - + + + 4 + + @@ -48,7 +57,523 @@ - + + + + Qt::Horizontal + + + + + + + + + false + + + + 0 + 0 + + + + Qt::RightToLeft + + + + + + + + + + false + + + + 0 + 0 + + + + Qt::RightToLeft + + + + + + + + + + false + + + + 0 + 0 + + + + Qt::RightToLeft + + + + + + + + + + false + + + + 0 + 0 + + + + Qt::RightToLeft + + + + + + + + + + false + + + + 0 + 0 + + + + Qt::RightToLeft + + + + + + + 16 + 16 + + + + + + + + false + + + + 0 + 0 + + + + Qt::RightToLeft + + + + + + + + + + false + + + + 0 + 0 + + + + Qt::RightToLeft + + + + + + + + + + false + + + + 0 + 0 + + + + Qt::RightToLeft + + + + + + + + + + false + + + + 0 + 0 + + + + Qt::RightToLeft + + + + + + + + + + false + + + + 0 + 0 + + + + Qt::RightToLeft + + + + + + + + + + false + + + + 0 + 0 + + + + Qt::RightToLeft + + + + + + + + + + false + + + + 0 + 0 + + + + Primary view + + + Qt::RightToLeft + + + + + + false + + + + + + + Secondary Views + + + Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft + + + + + + + false + + + + 0 + 0 + + + + Qt::RightToLeft + + + + + + + + + + + + Qt::Horizontal + + + + + + + true + + + + 0 + 0 + + + + + 90 + 230 + + + + 0 + + + + true + + + + 0 + 0 + + + + General + + + + + 0 + 7 + 231 + 191 + + + + + 0 + + + + + true + + + Auto scale / position + + + true + + + + + + + + + + + false + + + Scale + + + 2 + + + 0 + + + + + + + false + + + Primary x / y + + + 2 + + + 0 + + + + + + + false + + + Secondary dx / dy + + + 2 + + + 0 + + + + + + + + + + + false + + + + 0 + 0 + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + false + + + + 0 + 0 + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + false + + + + 0 + 0 + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + false + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + false + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + + + Qt::Horizontal + + + + + + + true + + + Show hidden + + + + + + + Show smooth + + + + + + + + + Axonometric + + + + + @@ -93,12 +618,12 @@ - Back + Right - Right + Back @@ -146,232 +671,6 @@ - - - - Qt::Horizontal - - - - - - - - - - - Secondary views - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - 0 - - - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Qt::Horizontal - - - - - - - - - true - - - Auto scale / position - - - true - - - - - - - - - - - false - - - Scale - - - - - - - false - - - Primary x / y - - - - - - - false - - - Secondary spacings - - - - - - - - - - - false - - - - 0 - 0 - - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - - false - - - - 0 - 0 - - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - false - - - - 0 - 0 - - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - - - - false - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - false - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - - - - - - - - Qt::Horizontal - - - - - - - true - - - Show hidden - - - - - - - Show smooth - - - diff --git a/src/Mod/Drawing/Templates/A3_Landscape.svg b/src/Mod/Drawing/Templates/A3_Landscape.svg index 4a98aed92..408973dbc 100644 --- a/src/Mod/Drawing/Templates/A3_Landscape.svg +++ b/src/Mod/Drawing/Templates/A3_Landscape.svg @@ -9,8 +9,9 @@ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:freecad="http://sourceforge.net/apps/mediawiki/free-cad/index.php?title=Svg_Namespace" - width="420" - height="297" + width="420mm" + height="297mm" + viewBox="0 0 420 297" version="1.1" id="svg2" sodipodi:version="0.32" @@ -576,9 +577,6 @@ bordercolor="#666666" pagecolor="#ffffff" id="base" - inkscape:zoom="1.7101889" - inkscape:cx="254.10366" - inkscape:cy="146.94782" inkscape:window-x="0" inkscape:window-y="20" inkscape:current-layer="svg2" diff --git a/src/Mod/Drawing/Templates/A4_Landscape.svg b/src/Mod/Drawing/Templates/A4_Landscape.svg index 07a09c2b8..52a36159d 100644 --- a/src/Mod/Drawing/Templates/A4_Landscape.svg +++ b/src/Mod/Drawing/Templates/A4_Landscape.svg @@ -8,8 +8,9 @@ xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - width="297" - height="210" + width="297mm" + height="210mm" + viewBox="0 0 297 210" version="1.1" id="svg2" sodipodi:version="0.32" @@ -903,9 +904,6 @@ bordercolor="#666666" pagecolor="#ffffff" id="base" - inkscape:zoom="3.5" - inkscape:cx="119.25908" - inkscape:cy="0.84879944" inkscape:window-x="0" inkscape:window-y="22" inkscape:current-layer="svg2" diff --git a/src/Mod/Drawing/Templates/A4_Simple.svg b/src/Mod/Drawing/Templates/A4_Simple.svg index 898ac22bc..6ec943487 100644 --- a/src/Mod/Drawing/Templates/A4_Simple.svg +++ b/src/Mod/Drawing/Templates/A4_Simple.svg @@ -7,7 +7,8 @@ version="1.1" baseProfile="full" width="297mm" - height="420mm"> + height="420mm" + viewBox="0 0 297 420"> diff --git a/src/Mod/Fem/App/CMakeLists.txt b/src/Mod/Fem/App/CMakeLists.txt index 97b2df0e2..ac9544ec4 100644 --- a/src/Mod/Fem/App/CMakeLists.txt +++ b/src/Mod/Fem/App/CMakeLists.txt @@ -64,7 +64,12 @@ SOURCE_GROUP("Module" FILES ${Mod_SRCS}) add_library(Fem SHARED ${Fem_SRCS}) target_link_libraries(Fem ${Fem_LIBS}) -fc_copy_script("Mod/Fem" "Fem" Init.py convert2TetGen.py) + + +fc_target_copy_resource(Fem + ${CMAKE_SOURCE_DIR}/src/Mod/Fem + ${CMAKE_BINARY_DIR}/Mod/Fem + Init.py convert2TetGen.py) if(MSVC) set_target_properties(Fem PROPERTIES SUFFIX ".pyd") diff --git a/src/Mod/Fem/CMakeLists.txt b/src/Mod/Fem/CMakeLists.txt index 2122e8717..4c42843ae 100644 --- a/src/Mod/Fem/CMakeLists.txt +++ b/src/Mod/Fem/CMakeLists.txt @@ -8,6 +8,8 @@ INSTALL( FILES Init.py InitGui.py + convert2TetGen.py + FemExample.py DESTINATION Mod/Fem ) diff --git a/src/Mod/Fem/Gui/CMakeLists.txt b/src/Mod/Fem/Gui/CMakeLists.txt index abdd2fd2a..8774505f4 100644 --- a/src/Mod/Fem/Gui/CMakeLists.txt +++ b/src/Mod/Fem/Gui/CMakeLists.txt @@ -51,7 +51,12 @@ SET(FemGui_SRCS add_library(FemGui SHARED ${FemGui_SRCS}) target_link_libraries(FemGui ${FemGui_LIBS}) -fc_copy_script("Mod/Fem" "FemGui" InitGui.py) + + +fc_target_copy_resource(FemGui + ${CMAKE_SOURCE_DIR}/src/Mod/Fem + ${CMAKE_BINARY_DIR}/Mod/Fem + InitGui.py) if(MSVC) set_target_properties(FemGui PROPERTIES SUFFIX ".pyd") diff --git a/src/Mod/Idf/CMakeLists.txt b/src/Mod/Idf/CMakeLists.txt index 124b8f3e6..d27534127 100644 --- a/src/Mod/Idf/CMakeLists.txt +++ b/src/Mod/Idf/CMakeLists.txt @@ -49,7 +49,7 @@ ADD_CUSTOM_TARGET(Idf ALL SOURCES ${all_files} ) -fc_copy_sources("Mod/Idf" "Idf" ${all_files}) +fc_copy_sources(Idf "${CMAKE_BINARY_DIR}/Mod/Idf" ${all_files}) INSTALL( FILES diff --git a/src/Mod/Image/App/CMakeLists.txt b/src/Mod/Image/App/CMakeLists.txt index 708947e79..b46f5a326 100644 --- a/src/Mod/Image/App/CMakeLists.txt +++ b/src/Mod/Image/App/CMakeLists.txt @@ -29,7 +29,12 @@ set(Image_SRCS add_library(Image SHARED ${Image_SRCS}) target_link_libraries(Image ${Image_LIBS}) -fc_copy_script("Mod/Image" "Image" Init.py) + + +fc_target_copy_resource(Image + ${CMAKE_SOURCE_DIR}/src/Mod/Image + ${CMAKE_BINARY_DIR}/Mod/Image + Init.py) if(MSVC) set_target_properties(Image PROPERTIES SUFFIX ".pyd") diff --git a/src/Mod/Image/Gui/CMakeLists.txt b/src/Mod/Image/Gui/CMakeLists.txt index c4af482fc..243b1b58d 100644 --- a/src/Mod/Image/Gui/CMakeLists.txt +++ b/src/Mod/Image/Gui/CMakeLists.txt @@ -54,7 +54,12 @@ SET(ImageGui_SRCS add_library(ImageGui SHARED ${ImageGui_SRCS}) target_link_libraries(ImageGui ${ImageGui_LIBS}) -fc_copy_script("Mod/Image" "ImageGui" InitGui.py) + + +fc_target_copy_resource(ImageGui + ${CMAKE_SOURCE_DIR}/src/Mod/Image + ${CMAKE_BINARY_DIR}/Mod/Image + InitGui.py) if(MSVC) set_target_properties(ImageGui PROPERTIES SUFFIX ".pyd") diff --git a/src/Mod/Import/Gui/CMakeLists.txt b/src/Mod/Import/Gui/CMakeLists.txt index 5068a8b85..7cd962a92 100644 --- a/src/Mod/Import/Gui/CMakeLists.txt +++ b/src/Mod/Import/Gui/CMakeLists.txt @@ -40,8 +40,12 @@ SET(ImportGui_SRCS add_library(ImportGui SHARED ${ImportGui_SRCS}) target_link_libraries(ImportGui ${ImportGui_LIBS}) -fc_copy_script("Mod/Import" "ImportGui" Init.py) -fc_copy_script("Mod/Import" "ImportGui" InitGui.py) + + +fc_target_copy_resource(ImportGui + ${CMAKE_SOURCE_DIR}/src/Mod/Import + ${CMAKE_BINARY_DIR}/Mod/Import + Init.py InitGui.py) if(MSVC) set_target_properties(ImportGui PROPERTIES SUFFIX ".pyd") diff --git a/src/Mod/Inspection/App/CMakeLists.txt b/src/Mod/Inspection/App/CMakeLists.txt index 6c68175b7..37116678b 100644 --- a/src/Mod/Inspection/App/CMakeLists.txt +++ b/src/Mod/Inspection/App/CMakeLists.txt @@ -35,7 +35,12 @@ SET(Inspection_SRCS add_library(Inspection SHARED ${Inspection_SRCS}) target_link_libraries(Inspection ${Inspection_LIBS}) -fc_copy_script("Mod/Inspection" "Inspection" Init.py) + + +fc_target_copy_resource(Inspection + ${CMAKE_SOURCE_DIR}/src/Mod/Inspection + ${CMAKE_BINARY_DIR}/Mod/Inspection + Init.py) if(MSVC) set_target_properties(Inspection PROPERTIES SUFFIX ".pyd") diff --git a/src/Mod/Inspection/Gui/CMakeLists.txt b/src/Mod/Inspection/Gui/CMakeLists.txt index 103f80456..b059194e3 100644 --- a/src/Mod/Inspection/Gui/CMakeLists.txt +++ b/src/Mod/Inspection/Gui/CMakeLists.txt @@ -52,7 +52,12 @@ SET(InspectionGui_SRCS add_library(InspectionGui SHARED ${InspectionGui_SRCS}) target_link_libraries(InspectionGui ${InspectionGui_LIBS}) -fc_copy_script("Mod/Inspection" "InspectionGui" InitGui.py) + + +fc_target_copy_resource(InspectionGui + ${CMAKE_SOURCE_DIR}/src/Mod/Inspection + ${CMAKE_BINARY_DIR}/Mod/Inspection + InitGui.py) if(MSVC) set_target_properties(InspectionGui PROPERTIES SUFFIX ".pyd") diff --git a/src/Mod/Machining_Distortion/CMakeLists.txt b/src/Mod/Machining_Distortion/CMakeLists.txt index fa2cad73c..6bf855e77 100644 --- a/src/Mod/Machining_Distortion/CMakeLists.txt +++ b/src/Mod/Machining_Distortion/CMakeLists.txt @@ -15,11 +15,11 @@ SET(MachDist_SRCS SOURCE_GROUP("" FILES ${MachDist_SRCS}) -ADD_CUSTOM_TARGET(MachDistortion ALL +ADD_CUSTOM_TARGET( ALL SOURCES ${MachDist_SRCS} ) -fc_copy_sources("Mod/Machining_Distortion" ${MachDist_SRCS}) +fc_copy_sources(MachDistortion "${CMAKE_BINARY_DIR}/Mod/Machining_Distortion" ${MachDist_SRCS}) INSTALL( diff --git a/src/Mod/Mesh/App/CMakeLists.txt b/src/Mod/Mesh/App/CMakeLists.txt index f267429e0..fc7e99653 100644 --- a/src/Mod/Mesh/App/CMakeLists.txt +++ b/src/Mod/Mesh/App/CMakeLists.txt @@ -331,8 +331,16 @@ endif(MSVC) add_library(Mesh SHARED ${Core_SRCS} ${WildMagic4_SRCS} ${Mesh_SRCS}) target_link_libraries(Mesh ${Mesh_LIBS}) -fc_copy_script ("Mod/Mesh" "Mesh" Init.py BuildRegularGeoms.py) -fc_copy_sources("Mod/Mesh" "Mesh" MeshTestsApp.py) + +fc_target_copy_resource(Mesh + ${CMAKE_SOURCE_DIR}/src/Mod/Mesh + ${CMAKE_BINARY_DIR}/Mod/Mesh + Init.py BuildRegularGeoms.py) + +fc_target_copy_resource(Mesh + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_BINARY_DIR}/Mod/Mesh + MeshTestsApp.py) if(MSVC) set_target_properties(Mesh PROPERTIES SUFFIX ".pyd") diff --git a/src/Mod/Mesh/Gui/CMakeLists.txt b/src/Mod/Mesh/Gui/CMakeLists.txt index 8d17921ab..9941cac13 100644 --- a/src/Mod/Mesh/Gui/CMakeLists.txt +++ b/src/Mod/Mesh/Gui/CMakeLists.txt @@ -109,7 +109,12 @@ SET(MeshGui_SRCS add_library(MeshGui SHARED ${MeshGui_SRCS}) target_link_libraries(MeshGui ${MeshGui_LIBS}) -fc_copy_script("Mod/Mesh" "MeshGui" InitGui.py) + + +fc_target_copy_resource(MeshGui + ${CMAKE_SOURCE_DIR}/src/Mod/Mesh + ${CMAKE_BINARY_DIR}/Mod/Mesh + InitGui.py) if(MSVC) set_target_properties(MeshGui PROPERTIES SUFFIX ".pyd") diff --git a/src/Mod/MeshPart/App/CMakeLists.txt b/src/Mod/MeshPart/App/CMakeLists.txt index a9e46eaf8..078523f1b 100644 --- a/src/Mod/MeshPart/App/CMakeLists.txt +++ b/src/Mod/MeshPart/App/CMakeLists.txt @@ -51,7 +51,12 @@ SET(MeshPart_SRCS add_library(MeshPart SHARED ${MeshPart_SRCS}) target_link_libraries(MeshPart ${MeshPart_LIBS}) -fc_copy_script("Mod/MeshPart" "MeshPart" Init.py) + + +fc_target_copy_resource(MeshPart + ${CMAKE_SOURCE_DIR}/src/Mod/MeshPart + ${CMAKE_BINARY_DIR}/Mod/MeshPart + Init.py) if(MSVC) set_target_properties(MeshPart PROPERTIES SUFFIX ".pyd") diff --git a/src/Mod/MeshPart/Gui/CMakeLists.txt b/src/Mod/MeshPart/Gui/CMakeLists.txt index 2a9b603a8..dfc68c4a6 100644 --- a/src/Mod/MeshPart/Gui/CMakeLists.txt +++ b/src/Mod/MeshPart/Gui/CMakeLists.txt @@ -54,7 +54,12 @@ SET(MeshPartGui_SRCS add_library(MeshPartGui SHARED ${MeshPartGui_SRCS}) target_link_libraries(MeshPartGui ${MeshPartGui_LIBS}) -fc_copy_script("Mod/MeshPart" "MeshPartGui" InitGui.py) + + +fc_target_copy_resource(MeshPartGui + ${CMAKE_SOURCE_DIR}/src/Mod/MeshPart + ${CMAKE_BINARY_DIR}/Mod/MeshPart + InitGui.py) if(MSVC) set_target_properties(MeshPartGui PROPERTIES SUFFIX ".pyd") diff --git a/src/Mod/Part/App/CMakeLists.txt b/src/Mod/Part/App/CMakeLists.txt index 40c81da59..bd0cb791a 100644 --- a/src/Mod/Part/App/CMakeLists.txt +++ b/src/Mod/Part/App/CMakeLists.txt @@ -241,7 +241,12 @@ SET(Part_Scripts add_library(Part SHARED ${Part_SRCS}) target_link_libraries(Part ${Part_LIBS}) -fc_copy_script("Mod/Part" "Part" ${Part_Scripts}) + + +fc_target_copy_resource(Part + ${CMAKE_SOURCE_DIR}/src/Mod/Part + ${CMAKE_BINARY_DIR}/Mod/Part + ${Part_Scripts}) if(MSVC) set_target_properties(Part PROPERTIES SUFFIX ".pyd") diff --git a/src/Mod/Part/CMakeLists.txt b/src/Mod/Part/CMakeLists.txt index 3f9ac4f8c..06ebf2ce6 100644 --- a/src/Mod/Part/CMakeLists.txt +++ b/src/Mod/Part/CMakeLists.txt @@ -8,6 +8,9 @@ INSTALL( FILES Init.py InitGui.py + MakeBottle.py + TestPartApp.py + TestPartGui.py DESTINATION Mod/Part ) diff --git a/src/Mod/Part/Gui/CMakeLists.txt b/src/Mod/Part/Gui/CMakeLists.txt index 38a984c5e..d9ff99f95 100644 --- a/src/Mod/Part/Gui/CMakeLists.txt +++ b/src/Mod/Part/Gui/CMakeLists.txt @@ -165,7 +165,12 @@ SET(PartGui_Scripts add_library(PartGui SHARED ${PartGui_SRCS}) target_link_libraries(PartGui ${PartGui_LIBS}) -fc_copy_script("Mod/Part" "PartGui" ${PartGui_Scripts}) + + +fc_target_copy_resource(PartGui + ${CMAKE_SOURCE_DIR}/src/Mod/Part + ${CMAKE_BINARY_DIR}/Mod/Part + ${PartGui_Scripts}) if(MSVC) set_target_properties(PartGui PROPERTIES SUFFIX ".pyd") diff --git a/src/Mod/PartDesign/App/CMakeLists.txt b/src/Mod/PartDesign/App/CMakeLists.txt index 0a87bd07d..49af69836 100644 --- a/src/Mod/PartDesign/App/CMakeLists.txt +++ b/src/Mod/PartDesign/App/CMakeLists.txt @@ -90,7 +90,12 @@ SET(PartDesign_Scripts add_library(PartDesign SHARED ${PartDesign_SRCS}) target_link_libraries(PartDesign ${PartDesign_LIBS}) -fc_copy_script("Mod/PartDesign" "PartDesign" ${PartDesign_Scripts}) + + +fc_target_copy_resource(PartDesign + ${CMAKE_SOURCE_DIR}/src/Mod/PartDesign + ${CMAKE_BINARY_DIR}/Mod/PartDesign + ${PartDesign_Scripts}) if(MSVC) set_target_properties(PartDesign PROPERTIES SUFFIX ".pyd") @@ -105,7 +110,9 @@ elseif(MINGW) else(MSVC) set_target_properties(PartDesign PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/Mod/PartDesign) set_target_properties(PartDesign PROPERTIES PREFIX "") - set_target_properties(PartDesign PROPERTIES INSTALL_RPATH ${INSTALL_RPATH}) + set_target_properties(PartDesign PROPERTIES INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/Mod/PartDesign) endif(MSVC) -INSTALL(TARGETS PartDesign DESTINATION lib) +# The PartDesign module must go to where the __init__.py file is +INSTALL(TARGETS PartDesign DESTINATION Mod/PartDesign) + diff --git a/src/Mod/PartDesign/CMakeLists.txt b/src/Mod/PartDesign/CMakeLists.txt index 3a7a0cc48..d00420484 100644 --- a/src/Mod/PartDesign/CMakeLists.txt +++ b/src/Mod/PartDesign/CMakeLists.txt @@ -6,8 +6,25 @@ endif(FREECAD_BUILD_GUI) INSTALL( FILES + __init__.py Init.py InitGui.py + TestPartDesignApp.py + TestPartDesignGui.py DESTINATION Mod/PartDesign ) + +INSTALL( + FILES + Scripts/__init__.py + Scripts/Gear.py + Scripts/DistanceBolt.py + Scripts/Epitrochoid.py + Scripts/RadialCopy.py + Scripts/Parallelepiped.py + Scripts/Spring.py + DESTINATION + Mod/PartDesign/Scripts +) + diff --git a/src/Mod/PartDesign/Gui/CMakeLists.txt b/src/Mod/PartDesign/Gui/CMakeLists.txt index 23ef7e9b1..8f6e26556 100644 --- a/src/Mod/PartDesign/Gui/CMakeLists.txt +++ b/src/Mod/PartDesign/Gui/CMakeLists.txt @@ -121,7 +121,12 @@ SET(PartDesignGui_SRCS add_library(PartDesignGui SHARED ${PartDesignGui_SRCS}) target_link_libraries(PartDesignGui ${PartDesignGui_LIBS}) -fc_copy_script("Mod/PartDesign" "PartDesignGui" ${PartDesignGui_Scripts}) + + +fc_target_copy_resource(PartDesignGui + ${CMAKE_SOURCE_DIR}/src/Mod/PartDesign + ${CMAKE_BINARY_DIR}/Mod/PartDesign + ${PartDesignGui_Scripts}) if(MSVC) set_target_properties(PartDesignGui PROPERTIES SUFFIX ".pyd") @@ -136,7 +141,9 @@ elseif(MINGW) else(MSVC) set_target_properties(PartDesignGui PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/Mod/PartDesign) set_target_properties(PartDesignGui PROPERTIES PREFIX "") - set_target_properties(PartDesignGui PROPERTIES INSTALL_RPATH ${INSTALL_RPATH}) + set_target_properties(PartDesignGui PROPERTIES INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/Mod/PartDesign) endif(MSVC) -INSTALL(TARGETS PartDesignGui DESTINATION lib) +# The PartDesign module must go to where the __init__.py file is +INSTALL(TARGETS PartDesignGui DESTINATION Mod/PartDesign) + diff --git a/src/Mod/Points/App/CMakeLists.txt b/src/Mod/Points/App/CMakeLists.txt index ef411469c..9cd657f98 100644 --- a/src/Mod/Points/App/CMakeLists.txt +++ b/src/Mod/Points/App/CMakeLists.txt @@ -44,7 +44,11 @@ add_library(Points SHARED ${Points_SRCS}) target_link_libraries(Points ${Points_LIBS}) -fc_copy_script("Mod/Points" "Points" Init.py) + +fc_target_copy_resource(Points + ${CMAKE_SOURCE_DIR}/src/Mod/Points + ${CMAKE_BINARY_DIR}/Mod/Points + Init.py) if(MSVC) set_target_properties(Points PROPERTIES SUFFIX ".pyd") diff --git a/src/Mod/Points/Gui/CMakeLists.txt b/src/Mod/Points/Gui/CMakeLists.txt index 60a59bcda..fab12ff44 100644 --- a/src/Mod/Points/Gui/CMakeLists.txt +++ b/src/Mod/Points/Gui/CMakeLists.txt @@ -54,7 +54,12 @@ SET(PointsGui_SRCS add_library(PointsGui SHARED ${PointsGui_SRCS}) target_link_libraries(PointsGui ${PointsGui_LIBS}) -fc_copy_script("Mod/Points" "PointsGui" InitGui.py) + + +fc_target_copy_resource(PointsGui + ${CMAKE_SOURCE_DIR}/src/Mod/Points + ${CMAKE_BINARY_DIR}/Mod/Points + InitGui.py) if(MSVC) set_target_properties(PointsGui PROPERTIES SUFFIX ".pyd") diff --git a/src/Mod/Raytracing/App/CMakeLists.txt b/src/Mod/Raytracing/App/CMakeLists.txt index 2ee33c178..359ecd9a2 100644 --- a/src/Mod/Raytracing/App/CMakeLists.txt +++ b/src/Mod/Raytracing/App/CMakeLists.txt @@ -51,15 +51,27 @@ SET(Raytracing_SRCS RaySegment.h ) +SET(Raytracing_Scripts + Init.py + RaytracingExample.py +) + SET(Raytracing_Templates Templates/ProjectStd.pov ) add_library(Raytracing SHARED ${Raytracing_SRCS}) target_link_libraries(Raytracing ${Raytracing_LIBS}) -fc_copy_script("Mod/Raytracing" "Raytracing" Init.py) -fc_copy_script("Mod/Raytracing" "Raytracing" RaytracingExample.py) -fc_copy_script("Mod/Raytracing" "Raytracing" ${Raytracing_Templates}) + +fc_target_copy_resource(Raytracing + ${CMAKE_SOURCE_DIR}/src/Mod/Raytracing + ${CMAKE_BINARY_DIR}/Mod/Raytracing + ${Raytracing_Scripts}) + +fc_target_copy_resource(Raytracing + ${CMAKE_SOURCE_DIR}/src/Mod/Raytracing + ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_DATADIR}/Mod/Raytracing + ${Raytracing_Templates}) if(MSVC) set_target_properties(Raytracing PROPERTIES SUFFIX ".pyd") diff --git a/src/Mod/Raytracing/CMakeLists.txt b/src/Mod/Raytracing/CMakeLists.txt index 9cb6bec71..416e7197a 100644 --- a/src/Mod/Raytracing/CMakeLists.txt +++ b/src/Mod/Raytracing/CMakeLists.txt @@ -8,6 +8,16 @@ INSTALL( FILES Init.py InitGui.py + RaytracingExample.py DESTINATION Mod/Raytracing ) + +INSTALL( + DIRECTORY + Templates + DESTINATION + ${CMAKE_INSTALL_DATADIR}/Mod/Raytracing + FILES_MATCHING PATTERN "*.pov*" +) + diff --git a/src/Mod/Raytracing/Gui/CMakeLists.txt b/src/Mod/Raytracing/Gui/CMakeLists.txt index 7b0b55457..fce924ce0 100644 --- a/src/Mod/Raytracing/Gui/CMakeLists.txt +++ b/src/Mod/Raytracing/Gui/CMakeLists.txt @@ -74,7 +74,12 @@ SET(RaytracingGui_SRCS add_library(RaytracingGui SHARED ${RaytracingGui_SRCS}) target_link_libraries(RaytracingGui ${RaytracingGui_LIBS}) -fc_copy_script("Mod/Raytracing" "RaytracingGui" InitGui.py) + + +fc_target_copy_resource(RaytracingGui + ${CMAKE_SOURCE_DIR}/src/Mod/Raytracing + ${CMAKE_BINARY_DIR}/Mod/Raytracing + InitGui.py) if(MSVC) set_target_properties(RaytracingGui PROPERTIES SUFFIX ".pyd") diff --git a/src/Mod/ReverseEngineering/App/CMakeLists.txt b/src/Mod/ReverseEngineering/App/CMakeLists.txt index f4256a878..e62bf7e64 100644 --- a/src/Mod/ReverseEngineering/App/CMakeLists.txt +++ b/src/Mod/ReverseEngineering/App/CMakeLists.txt @@ -32,7 +32,12 @@ SET(Reen_SRCS add_library(ReverseEngineering SHARED ${Reen_SRCS}) target_link_libraries(ReverseEngineering ${Reen_LIBS}) -fc_copy_script("Mod/ReverseEngineering" "ReverseEngineering" Init.py) + + +fc_target_copy_resource(ReverseEngineering + ${CMAKE_SOURCE_DIR}/src/Mod/ReverseEngineering + ${CMAKE_BINARY_DIR}/Mod/ReverseEngineering + Init.py) if(MSVC) set_target_properties(ReverseEngineering PROPERTIES SUFFIX ".pyd") diff --git a/src/Mod/ReverseEngineering/Gui/CMakeLists.txt b/src/Mod/ReverseEngineering/Gui/CMakeLists.txt index a60b0ba90..9a775bcbd 100644 --- a/src/Mod/ReverseEngineering/Gui/CMakeLists.txt +++ b/src/Mod/ReverseEngineering/Gui/CMakeLists.txt @@ -39,7 +39,12 @@ SET(ReenGui_SRCS add_library(ReverseEngineeringGui SHARED ${ReenGui_SRCS}) target_link_libraries(ReverseEngineeringGui ${ReenGui_LIBS}) -fc_copy_script("Mod/ReverseEngineering" "ReverseEngineeringGui" InitGui.py) + + +fc_target_copy_resource(ReverseEngineeringGui + ${CMAKE_SOURCE_DIR}/src/Mod/ReverseEngineering + ${CMAKE_BINARY_DIR}/Mod/ReverseEngineering + InitGui.py) if(MSVC) set_target_properties(ReverseEngineeringGui PROPERTIES SUFFIX ".pyd") diff --git a/src/Mod/Robot/App/CMakeLists.txt b/src/Mod/Robot/App/CMakeLists.txt index 1438841e3..6af950f3c 100644 --- a/src/Mod/Robot/App/CMakeLists.txt +++ b/src/Mod/Robot/App/CMakeLists.txt @@ -101,6 +101,13 @@ SOURCE_GROUP("KDL" FILES ${KDL_SRCS} ${KDL_HPPS} ${UTIL_SRCS} ${UTIL_HPPS} ) SOURCE_GROUP("Python" FILES ${Python_SRCS}) SOURCE_GROUP("Module" FILES ${Mod_SRCS}) +SET(Robot_Scripts + Init.py + KukaExporter.py + RobotExample.py + RobotExampleTrajectoryOutOfShapes.py +) + SET(Robot_Resources Lib/Kuka/kr500_1.wrl Lib/Kuka/kr500_1.csv @@ -114,15 +121,21 @@ SET(Robot_Resources Lib/Kuka/kr125_3.wrl Lib/Kuka/kr_125.csv Lib/Kuka/kr125_2.pdf - KukaExporter.py - RobotExample.py - RobotExampleTrajectoryOutOfShapes.py ) add_library(Robot SHARED ${Robot_SRCS}) target_link_libraries(Robot ${Robot_LIBS}) -fc_copy_script("Mod/Robot" "Robot" Init.py) -fc_copy_script("Mod/Robot" "Robot" ${Robot_Resources}) + +fc_target_copy_resource(Robot + ${CMAKE_SOURCE_DIR}/src/Mod/Robot + ${CMAKE_BINARY_DIR}/Mod/Robot + ${Robot_Scripts}) + +fc_target_copy_resource(Robot + ${CMAKE_SOURCE_DIR}/src/Mod/Robot + ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_DATADIR}/Mod/Robot + ${Robot_Resources}) + if(MSVC) set_target_properties(Robot PROPERTIES SUFFIX ".pyd") diff --git a/src/Mod/Robot/CMakeLists.txt b/src/Mod/Robot/CMakeLists.txt index fb292b687..750eb19bf 100644 --- a/src/Mod/Robot/CMakeLists.txt +++ b/src/Mod/Robot/CMakeLists.txt @@ -8,6 +8,20 @@ INSTALL( FILES Init.py InitGui.py + KukaExporter.py + MovieTool.py + RobotExample.py + RobotExampleTrajectoryOutOfShapes.py DESTINATION Mod/Robot ) + +INSTALL( + DIRECTORY + Lib + DESTINATION + ${CMAKE_INSTALL_DATADIR}/Mod/Robot + PATTERN "Makefile*" EXCLUDE + PATTERN "*.pdf" EXCLUDE +) + diff --git a/src/Mod/Robot/Gui/CMakeLists.txt b/src/Mod/Robot/Gui/CMakeLists.txt index afef07a61..fd0e29f10 100644 --- a/src/Mod/Robot/Gui/CMakeLists.txt +++ b/src/Mod/Robot/Gui/CMakeLists.txt @@ -146,8 +146,12 @@ SET(RobotGui_SRCS add_library(RobotGui SHARED ${RobotGui_SRCS}) target_link_libraries(RobotGui ${RobotGui_LIBS}) -fc_copy_script("Mod/Robot" "RobotGui" InitGui.py) -fc_copy_script("Mod/Robot" "RobotGui" MovieTool.py) + + +fc_target_copy_resource(RobotGui + ${CMAKE_SOURCE_DIR}/src/Mod/Robot + ${CMAKE_BINARY_DIR}/Mod/Robot + InitGui.py MovieTool.py) if(MSVC) set_target_properties(RobotGui PROPERTIES SUFFIX ".pyd") diff --git a/src/Mod/Sandbox/App/CMakeLists.txt b/src/Mod/Sandbox/App/CMakeLists.txt index 88e3c558d..48ffe2569 100644 --- a/src/Mod/Sandbox/App/CMakeLists.txt +++ b/src/Mod/Sandbox/App/CMakeLists.txt @@ -31,7 +31,12 @@ SET(Sandbox_SRCS add_library(Sandbox SHARED ${Sandbox_SRCS}) target_link_libraries(Sandbox ${Sandbox_LIBS}) -fc_copy_script("Mod/Sandbox" "Sandbox" Init.py) + + +fc_target_copy_resource(Sandbox + ${CMAKE_SOURCE_DIR}/src/Mod/Sandbox + ${CMAKE_BINARY_DIR}/Mod/Sandbox + Init.py) if(MSVC) set_target_properties(Sandbox PROPERTIES SUFFIX ".pyd") diff --git a/src/Mod/Sandbox/Gui/CMakeLists.txt b/src/Mod/Sandbox/Gui/CMakeLists.txt index 5549b23e9..eef1a96ad 100644 --- a/src/Mod/Sandbox/Gui/CMakeLists.txt +++ b/src/Mod/Sandbox/Gui/CMakeLists.txt @@ -42,7 +42,12 @@ SET(SandboxGui_SRCS add_library(SandboxGui SHARED ${SandboxGui_SRCS}) target_link_libraries(SandboxGui ${SandboxGui_LIBS}) -fc_copy_script("Mod/Sandbox" "SandboxGui" InitGui.py) + + +fc_target_copy_resource(SandboxGui + ${CMAKE_SOURCE_DIR}/src/Mod/Sandbox + ${CMAKE_BINARY_DIR}/Mod/Sandbox + InitGui.py) if(MSVC) set_target_properties(SandboxGui PROPERTIES SUFFIX ".pyd") diff --git a/src/Mod/Ship/CMakeLists.txt b/src/Mod/Ship/CMakeLists.txt index 9f86e5e4a..9a7a0b2e3 100644 --- a/src/Mod/Ship/CMakeLists.txt +++ b/src/Mod/Ship/CMakeLists.txt @@ -77,7 +77,7 @@ ADD_CUSTOM_TARGET(Ship ALL SOURCES ${all_files} ) -fc_copy_sources("Mod/Ship" "Ship" ${all_files}) +fc_copy_sources(Ship "${CMAKE_BINARY_DIR}/Mod/Ship" ${all_files}) INSTALL( FILES diff --git a/src/Mod/Sketcher/App/CMakeLists.txt b/src/Mod/Sketcher/App/CMakeLists.txt index 9acc4d2cb..e1f39d46e 100644 --- a/src/Mod/Sketcher/App/CMakeLists.txt +++ b/src/Mod/Sketcher/App/CMakeLists.txt @@ -106,7 +106,12 @@ SET(Sketcher_Scripts add_library(Sketcher SHARED ${Sketcher_SRCS}) target_link_libraries(Sketcher ${Sketcher_LIBS}) -fc_copy_script("Mod/Sketcher" "Sketcher" ${Sketcher_Scripts}) + + +fc_target_copy_resource(Sketcher + ${CMAKE_SOURCE_DIR}/src/Mod/Sketcher + ${CMAKE_BINARY_DIR}/Mod/Sketcher + ${Sketcher_Scripts}) if(MSVC) set_target_properties(Sketcher PROPERTIES SUFFIX ".pyd") diff --git a/src/Mod/Sketcher/CMakeLists.txt b/src/Mod/Sketcher/CMakeLists.txt index 9966c52ba..703e561b2 100644 --- a/src/Mod/Sketcher/CMakeLists.txt +++ b/src/Mod/Sketcher/CMakeLists.txt @@ -8,6 +8,10 @@ INSTALL( FILES Init.py InitGui.py + SketcherExample.py + TestSketcherApp.py + TestSketcherGui.py DESTINATION Mod/Sketcher ) + diff --git a/src/Mod/Sketcher/Gui/CMakeLists.txt b/src/Mod/Sketcher/Gui/CMakeLists.txt index f5ad36ab6..d2b6ca04a 100644 --- a/src/Mod/Sketcher/Gui/CMakeLists.txt +++ b/src/Mod/Sketcher/Gui/CMakeLists.txt @@ -98,7 +98,12 @@ SET(SketcherGui_Scripts add_library(SketcherGui SHARED ${SketcherGui_SRCS}) target_link_libraries(SketcherGui ${SketcherGui_LIBS}) -fc_copy_script("Mod/Sketcher" "SketcherGui" ${SketcherGui_Scripts}) + + +fc_target_copy_resource(SketcherGui + ${CMAKE_SOURCE_DIR}/src/Mod/Sketcher + ${CMAKE_BINARY_DIR}/Mod/Sketcher + ${SketcherGui_Scripts}) if(MSVC) set_target_properties(SketcherGui PROPERTIES SUFFIX ".pyd") diff --git a/src/Mod/Start/App/CMakeLists.txt b/src/Mod/Start/App/CMakeLists.txt index 0a56332a8..43a5b3c44 100644 --- a/src/Mod/Start/App/CMakeLists.txt +++ b/src/Mod/Start/App/CMakeLists.txt @@ -22,7 +22,12 @@ SET(Start_SRCS add_library(Start SHARED ${Start_SRCS}) target_link_libraries(Start ${Start_LIBS}) -fc_copy_script("Mod/Start" "Start" Init.py) + + +fc_target_copy_resource(Start + ${CMAKE_SOURCE_DIR}/src/Mod/Start + ${CMAKE_BINARY_DIR}/Mod/Start + Init.py) if(MSVC) set_target_properties(Start PROPERTIES SUFFIX ".pyd") diff --git a/src/Mod/Start/Gui/CMakeLists.txt b/src/Mod/Start/Gui/CMakeLists.txt index 13329d4d0..54bdc5c5e 100644 --- a/src/Mod/Start/Gui/CMakeLists.txt +++ b/src/Mod/Start/Gui/CMakeLists.txt @@ -27,8 +27,13 @@ SET(StartGui_SRCS Workbench.h ) -SET(StartPage_Resources +SET(StartPage_Scripts + InitGui.py StartPage/StartPage.py + StartPage/__init__.py +) + +SET(StartPage_Resources StartPage/PartDesign.py StartPage/ArchDesign.py StartPage/DefaultWorkbench.py @@ -38,7 +43,6 @@ SET(StartPage_Resources StartPage/LoadDrawingExample.py StartPage/LoadRobotExample.py StartPage/Background.jpg - StartPage/__init__.py StartPage/FreeCAD.png StartPage/ArchDesign.png StartPage/PartDesign.png @@ -54,8 +58,16 @@ SET(StartPage_Resources add_library(StartGui SHARED ${StartGui_SRCS}) target_link_libraries(StartGui ${StartGui_LIBS}) -fc_copy_script("Mod/Start" "StartGui" InitGui.py) -fc_copy_script("Mod/Start" "StartGui" ${StartPage_Resources}) + +fc_target_copy_resource(StartGui + ${CMAKE_SOURCE_DIR}/src/Mod/Start + ${CMAKE_BINARY_DIR}/Mod/Start + ${StartPage_Scripts}) + +fc_target_copy_resource(StartGui + ${CMAKE_SOURCE_DIR}/src/Mod/Start + ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_DATADIR}/Mod/Start + ${StartPage_Resources}) if(MSVC) set_target_properties(StartGui PROPERTIES SUFFIX ".pyd") diff --git a/src/Mod/Start/StartPage/CMakeLists.txt b/src/Mod/Start/StartPage/CMakeLists.txt index 624588115..19c59fcf3 100644 --- a/src/Mod/Start/StartPage/CMakeLists.txt +++ b/src/Mod/Start/StartPage/CMakeLists.txt @@ -26,7 +26,11 @@ SET(StartPage_DATA web.png ) -INSTALL(FILES ${StartPage_SRCS} ${StartPage_DATA} +INSTALL(FILES ${StartPage_SRCS} DESTINATION Mod/Start/StartPage ) +INSTALL(FILES ${StartPage_DATA} + DESTINATION ${CMAKE_INSTALL_DATADIR}/Mod/Start/StartPage +) + diff --git a/src/Mod/Surfaces/CMakeLists.txt b/src/Mod/Surfaces/CMakeLists.txt index edf782c51..0aee96c8b 100644 --- a/src/Mod/Surfaces/CMakeLists.txt +++ b/src/Mod/Surfaces/CMakeLists.txt @@ -69,7 +69,7 @@ ADD_CUSTOM_TARGET(Surfaces ALL SOURCES ${all_files} ) -fc_copy_sources("Mod/Surfaces" "Surfaces" ${all_files}) +fc_copy_sources(Surfaces "${CMAKE_BINARY_DIR}/Mod/Surfaces" ${all_files}) INSTALL( FILES diff --git a/src/Mod/Test/CMakeLists.txt b/src/Mod/Test/CMakeLists.txt index ec02a2805..8e0aae840 100644 --- a/src/Mod/Test/CMakeLists.txt +++ b/src/Mod/Test/CMakeLists.txt @@ -18,7 +18,7 @@ ADD_CUSTOM_TARGET(Test ALL SOURCES ${Test_SRCS} ) -fc_copy_sources("Mod/Test" "Test" ${Test_SRCS}) +fc_copy_sources(Test "${CMAKE_BINARY_DIR}/Mod/Test" ${Test_SRCS}) INSTALL( FILES diff --git a/src/Mod/Test/Gui/CMakeLists.txt b/src/Mod/Test/Gui/CMakeLists.txt index 4ec2b53c5..9b8b67252 100644 --- a/src/Mod/Test/Gui/CMakeLists.txt +++ b/src/Mod/Test/Gui/CMakeLists.txt @@ -44,13 +44,16 @@ SET(TestGui_SRCS PreCompiled.cpp PreCompiled.h ) +SET(TestGuiPy_SRCS + qtunittest.py +) add_library(QtUnitGui SHARED ${TestGui_SRCS}) target_link_libraries(QtUnitGui ${TestGui_LIBS}) add_dependencies(QtUnitGui Test) -fc_copy_sources_outpath("Mod/Test" "QtUnitGui" qtunittest.py) +fc_copy_sources(QtUnitGui "${CMAKE_BINARY_DIR}/Mod/Test" qtunittest.py) if(MSVC) set_target_properties(QtUnitGui PROPERTIES SUFFIX ".pyd") @@ -69,3 +72,5 @@ else(MSVC) endif(MSVC) INSTALL(TARGETS QtUnitGui DESTINATION lib) +INSTALL(FILES ${TestGuiPy_SRCS} DESTINATION Mod/Test) + diff --git a/src/Mod/Web/Gui/CMakeLists.txt b/src/Mod/Web/Gui/CMakeLists.txt index 70747a1d4..2aa8fcb16 100644 --- a/src/Mod/Web/Gui/CMakeLists.txt +++ b/src/Mod/Web/Gui/CMakeLists.txt @@ -36,8 +36,12 @@ SOURCE_GROUP("Moc" FILES ${SketcherGui_MOC_SRCS}) add_library(WebGui SHARED ${WebGui_SRCS}) target_link_libraries(WebGui ${WebGui_LIBS}) -fc_copy_script("Mod/Web" "WebGui" InitGui.py) -fc_copy_script("Mod/Web" "WebGui" Init.py) + + +fc_target_copy_resource(WebGui + ${CMAKE_SOURCE_DIR}/src/Mod/Web + ${CMAKE_BINARY_DIR}/Mod/Web + Init.py InitGui.py) if(MSVC) set_target_properties(WebGui PROPERTIES SUFFIX ".pyd") diff --git a/src/Tools/updateppa.py b/src/Tools/updateppa.py new file mode 100644 index 000000000..069c7e6e8 --- /dev/null +++ b/src/Tools/updateppa.py @@ -0,0 +1,46 @@ +import sys +from os import chdir +from os import path +from tempfile import gettempdir + +from bzrlib.transport import get_transport +from bzrlib.branch import Branch +from bzrlib.workingtree import WorkingTree + +def runUpdate(filename): + branch = "versioning.git" + REMOTE_URL="bzr+ssh://bazaar.launchpad.net/~freecad-maintainers/freecad/%s" % (branch) + PUSHTO_URL="bzr+ssh://bazaar.launchpad.net/~freecad-maintainers/freecad/%s" % (branch) + LOCAL_BRANCH=path.join(gettempdir(),branch) + + # Location of branch on Launchpad + remote_branch = Branch.open(REMOTE_URL) + + # Location of branch on local system + local_branch = remote_branch.bzrdir.sprout(LOCAL_BRANCH).open_branch() + + # Change a file in the local branch + try: + wf = open(LOCAL_BRANCH + "/src/Build/Version.h", 'w') + rf = open(filename, 'r') + except IOError, error: + raise IOError, error + else: + wf.write(rf.read()) + wf.close() + + # Commit the change + tree = WorkingTree.open(LOCAL_BRANCH) + tree.commit("Update version number") + + # Push back to Launchpad + #transport = get_transport(PUSHTO_URL) + #local_branch.create_clone_on_transport(transport) + +def main(): + runUpdate(sys.argv[1]) + +if __name__ == "__main__": + main() + + diff --git a/src/WindowsInstaller/FreeCAD.wxs b/src/WindowsInstaller/FreeCAD.wxs index 7a86e7a3c..c6ebcc680 100644 --- a/src/WindowsInstaller/FreeCAD.wxs +++ b/src/WindowsInstaller/FreeCAD.wxs @@ -151,12 +151,13 @@ - + + diff --git a/src/WindowsInstaller/FreeCADData.wxs b/src/WindowsInstaller/FreeCADData.wxs index 6cfb9b754..5244bf9a2 100644 --- a/src/WindowsInstaller/FreeCADData.wxs +++ b/src/WindowsInstaller/FreeCADData.wxs @@ -23,7 +23,7 @@ Juergen Riegel 2011 --> - + @@ -31,16 +31,71 @@ - + + - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/WindowsInstaller/LibPack.wxs b/src/WindowsInstaller/LibPack.wxs index b42bd2834..cbe94cdc6 100644 --- a/src/WindowsInstaller/LibPack.wxs +++ b/src/WindowsInstaller/LibPack.wxs @@ -77,6 +77,7 @@ --> + diff --git a/src/WindowsInstaller/ModArch.wxi b/src/WindowsInstaller/ModArch.wxi index 94f6217c4..61c1f2913 100644 --- a/src/WindowsInstaller/ModArch.wxi +++ b/src/WindowsInstaller/ModArch.wxi @@ -32,7 +32,7 @@ - + diff --git a/src/WindowsInstaller/ModDrawing.wxi b/src/WindowsInstaller/ModDrawing.wxi index 4c22937e3..7060491bb 100644 --- a/src/WindowsInstaller/ModDrawing.wxi +++ b/src/WindowsInstaller/ModDrawing.wxi @@ -22,17 +22,12 @@ Juergen Riegel 2008 --> - + - - - - - \ No newline at end of file diff --git a/src/WindowsInstaller/ModRobot.wxi b/src/WindowsInstaller/ModRobot.wxi index e190e25ff..932f8a8d9 100644 --- a/src/WindowsInstaller/ModRobot.wxi +++ b/src/WindowsInstaller/ModRobot.wxi @@ -32,19 +32,5 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/WindowsInstaller/ModStart.wxi b/src/WindowsInstaller/ModStart.wxi index 47381a780..c730abb85 100644 --- a/src/WindowsInstaller/ModStart.wxi +++ b/src/WindowsInstaller/ModStart.wxi @@ -29,32 +29,11 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + - \ No newline at end of file