From 483e64f368e63db4aaf230256acf7d830c9d2cef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Tr=C3=B6ger?= Date: Tue, 12 Apr 2016 19:10:19 +0200 Subject: [PATCH] remove unneeded orig files --- src/App/Application.cpp.orig | 2169 --------- src/App/CMakeLists.txt.orig | 229 - src/App/Document.h.orig | 375 -- src/Gui/Selection.cpp.orig | 1313 ------ src/Gui/View3DInventorViewer.cpp.orig | 2759 ----------- src/Mod/Assembly/App/AppAssemblyPy.cpp.orig | 98 - .../Assembly/Gui/Resources/Assembly.qrc.orig | 81 - src/Mod/Import/App/AppImportPy.cpp.orig | 664 --- src/Mod/PartDesign/App/AppPartDesign.cpp.orig | 118 - .../PartDesign/App/FeatureChamfer.cpp.orig | 153 - .../PartDesign/App/FeatureDressUp.cpp.orig | 171 - src/Mod/PartDesign/App/FeatureFillet.cpp.orig | 155 - src/Mod/PartDesign/Gui/Command.cpp.orig | 1934 -------- .../PartDesign/Gui/FeaturePickDialog.cpp.orig | 166 - .../Gui/Resources/PartDesign.qrc.orig | 79 - .../Gui/TaskChamferParameters.h.orig | 90 - .../Gui/TaskDraftParameters.cpp.orig | 332 -- .../PartDesign/Gui/TaskDraftParameters.h.orig | 96 - .../Gui/TaskFilletParameters.h.orig | 90 - .../Gui/TaskGrooveParameters.cpp.orig | 458 -- .../Gui/TaskGrooveParameters.h.orig | 117 - .../Gui/TaskLinearPatternParameters.cpp.orig | 445 -- .../Gui/TaskMirroredParameters.cpp.orig | 361 -- .../Gui/TaskMultiTransformParameters.cpp.orig | 512 -- .../PartDesign/Gui/TaskPadParameters.cpp.orig | 507 -- .../PartDesign/Gui/TaskPadParameters.h.orig | 121 - .../Gui/TaskPocketParameters.cpp.orig | 453 -- .../Gui/TaskPocketParameters.h.orig | 119 - .../Gui/TaskPolarPatternParameters.cpp.orig | 435 -- .../Gui/TaskRevolutionParameters.cpp.orig | 410 -- .../Gui/TaskRevolutionParameters.h.orig | 111 - .../Gui/TaskScaledParameters.cpp.orig | 273 -- .../Gui/TaskTransformedParameters.cpp.orig | 519 -- .../Gui/TaskTransformedParameters.h.orig | 247 - .../Gui/ViewProviderTransformed.cpp.orig | 410 -- src/Mod/PartDesign/InitGui.py.orig | 76 - src/Mod/Sketcher/App/SketchObject.cpp.orig | 4180 ----------------- 37 files changed, 20826 deletions(-) delete mode 100644 src/App/Application.cpp.orig delete mode 100644 src/App/CMakeLists.txt.orig delete mode 100644 src/App/Document.h.orig delete mode 100644 src/Gui/Selection.cpp.orig delete mode 100644 src/Gui/View3DInventorViewer.cpp.orig delete mode 100644 src/Mod/Assembly/App/AppAssemblyPy.cpp.orig delete mode 100644 src/Mod/Assembly/Gui/Resources/Assembly.qrc.orig delete mode 100644 src/Mod/Import/App/AppImportPy.cpp.orig delete mode 100644 src/Mod/PartDesign/App/AppPartDesign.cpp.orig delete mode 100644 src/Mod/PartDesign/App/FeatureChamfer.cpp.orig delete mode 100644 src/Mod/PartDesign/App/FeatureDressUp.cpp.orig delete mode 100644 src/Mod/PartDesign/App/FeatureFillet.cpp.orig delete mode 100644 src/Mod/PartDesign/Gui/Command.cpp.orig delete mode 100644 src/Mod/PartDesign/Gui/FeaturePickDialog.cpp.orig delete mode 100644 src/Mod/PartDesign/Gui/Resources/PartDesign.qrc.orig delete mode 100644 src/Mod/PartDesign/Gui/TaskChamferParameters.h.orig delete mode 100644 src/Mod/PartDesign/Gui/TaskDraftParameters.cpp.orig delete mode 100644 src/Mod/PartDesign/Gui/TaskDraftParameters.h.orig delete mode 100644 src/Mod/PartDesign/Gui/TaskFilletParameters.h.orig delete mode 100644 src/Mod/PartDesign/Gui/TaskGrooveParameters.cpp.orig delete mode 100644 src/Mod/PartDesign/Gui/TaskGrooveParameters.h.orig delete mode 100644 src/Mod/PartDesign/Gui/TaskLinearPatternParameters.cpp.orig delete mode 100644 src/Mod/PartDesign/Gui/TaskMirroredParameters.cpp.orig delete mode 100644 src/Mod/PartDesign/Gui/TaskMultiTransformParameters.cpp.orig delete mode 100644 src/Mod/PartDesign/Gui/TaskPadParameters.cpp.orig delete mode 100644 src/Mod/PartDesign/Gui/TaskPadParameters.h.orig delete mode 100644 src/Mod/PartDesign/Gui/TaskPocketParameters.cpp.orig delete mode 100644 src/Mod/PartDesign/Gui/TaskPocketParameters.h.orig delete mode 100644 src/Mod/PartDesign/Gui/TaskPolarPatternParameters.cpp.orig delete mode 100644 src/Mod/PartDesign/Gui/TaskRevolutionParameters.cpp.orig delete mode 100644 src/Mod/PartDesign/Gui/TaskRevolutionParameters.h.orig delete mode 100644 src/Mod/PartDesign/Gui/TaskScaledParameters.cpp.orig delete mode 100644 src/Mod/PartDesign/Gui/TaskTransformedParameters.cpp.orig delete mode 100644 src/Mod/PartDesign/Gui/TaskTransformedParameters.h.orig delete mode 100644 src/Mod/PartDesign/Gui/ViewProviderTransformed.cpp.orig delete mode 100644 src/Mod/PartDesign/InitGui.py.orig delete mode 100644 src/Mod/Sketcher/App/SketchObject.cpp.orig diff --git a/src/App/Application.cpp.orig b/src/App/Application.cpp.orig deleted file mode 100644 index e123c760c..000000000 --- a/src/App/Application.cpp.orig +++ /dev/null @@ -1,2169 +0,0 @@ -/*************************************************************************** - * (c) Juergen Riegel (juergen.riegel@web.de) 2002 * - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU Library General Public License (LGPL) * - * as published by the Free Software Foundation; either version 2 of * - * the License, or (at your option) any later version. * - * for detail see the LICENCE text file. * - * * - * FreeCAD is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with FreeCAD; if not, write to the Free Software * - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * - * USA * - * * - * Juergen Riegel 2002 * - ***************************************************************************/ - - - -#include "PreCompiled.h" - -#ifndef _PreComp_ -# include -# include -# include -# if defined(FC_OS_LINUX) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD) -# include -# include -# include -# elif defined(__MINGW32__) -# define WINVER 0x502 // needed for SetDllDirectory -# include -# endif -# include -# include -# include -#endif - -#ifdef FC_OS_WIN32 -# include -#endif - - - -#include "Application.h" -#include "Document.h" - -// FreeCAD Base header -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "GeoFeature.h" -#include "FeatureTest.h" -#include "FeaturePython.h" -#include "ComplexGeoData.h" -#include "Property.h" -#include "PropertyContainer.h" -#include "PropertyUnits.h" -#include "PropertyFile.h" -#include "PropertyLinks.h" -#include "PropertyPythonObject.h" -#include "PropertyExpressionEngine.h" -#include "Document.h" -#include "DocumentObjectGroup.h" -#include "DocumentObjectFileIncluded.h" -#include "InventorObject.h" -#include "VRMLObject.h" -#include "Annotation.h" -#include "MeasureDistance.h" -#include "Placement.h" -#include "Plane.h" -#include "MaterialObject.h" -#include "Expression.h" - -// If you stumble here, run the target "BuildExtractRevision" on Windows systems -// or the Python script "SubWCRev.py" on Linux based systems which builds -// src/Build/Version.h. Or create your own from src/Build/Version.h.in! -#include -#include "Branding.h" - -#include -#include -#include -#include -#include -#include -#include - -using namespace App; -using namespace std; -using namespace boost; -using namespace boost::program_options; - - -// scriptings (scripts are build in but can be overridden by command line option) -#include "InitScript.h" -#include "TestScript.h" - -#ifdef _MSC_VER // New handler for Microsoft Visual C++ compiler -# include -# include // VC exception handling -#else // Ansi C/C++ new handler -# include -#endif - - -//using Base::GetConsole; -using namespace Base; -using namespace App; -using namespace std; - - -//========================================================================== -// Application -//========================================================================== - -ParameterManager *App::Application::_pcSysParamMngr; -ParameterManager *App::Application::_pcUserParamMngr; -Base::ConsoleObserverStd *Application::_pConsoleObserverStd =0; -Base::ConsoleObserverFile *Application::_pConsoleObserverFile =0; - -AppExport std::map Application::mConfig; -BaseExport extern PyObject* Base::BaseExceptionFreeCADError; - - -//************************************************************************** -// Construction and destruction - -PyDoc_STRVAR(FreeCAD_doc, - "The functions in the FreeCAD module allow working with documents.\n" - "The FreeCAD instance provides a list of references of documents which\n" - "can be addressed by a string. Hence the document name must be unique.\n" - "\n" - "The document has the read-only attribute FileName which points to the\n" - "file the document should be stored to.\n" - ); - -PyDoc_STRVAR(Console_doc, - "FreeCAD Console\n" - ); - -Application::Application(ParameterManager * /*pcSysParamMngr*/, - ParameterManager * /*pcUserParamMngr*/, - std::map &mConfig) - ://_pcSysParamMngr(pcSysParamMngr), - //_pcUserParamMngr(pcUserParamMngr), - _mConfig(mConfig), - _pActiveDoc(0) -{ - //_hApp = new ApplicationOCC; - mpcPramManager["System parameter"] = _pcSysParamMngr; - mpcPramManager["User parameter"] = _pcUserParamMngr; - - - // setting up Python binding - Base::PyGILStateLocker lock; - PyObject* pAppModule = Py_InitModule3("FreeCAD", Application::Methods, FreeCAD_doc); - Py::Module(pAppModule).setAttr(std::string("ActiveDocument"),Py::None()); - - PyObject* pConsoleModule = Py_InitModule3("__FreeCADConsole__", ConsoleSingleton::Methods, Console_doc); - - // introducing additional classes - - // NOTE: To finish the initialization of our own type objects we must - // call PyType_Ready, otherwise we run into a segmentation fault, later on. - // This function is responsible for adding inherited slots from a type's base class. - if (PyType_Ready(&Base::VectorPy::Type) < 0) return; - union PyType_Object pyVecType = {&Base::VectorPy::Type}; - PyModule_AddObject(pAppModule, "Vector", pyVecType.o); - - if (PyType_Ready(&Base::MatrixPy::Type) < 0) return; - union PyType_Object pyMtxType = {&Base::MatrixPy::Type}; - PyModule_AddObject(pAppModule, "Matrix", pyMtxType.o); - - if (PyType_Ready(&Base::BoundBoxPy::Type) < 0) return; - union PyType_Object pyBoundBoxType = {&Base::BoundBoxPy::Type}; - PyModule_AddObject(pAppModule, "BoundBox", pyBoundBoxType.o); - - if (PyType_Ready(&Base::PlacementPy::Type) < 0) return; - union PyType_Object pyPlacementPyType = {&Base::PlacementPy::Type}; - PyModule_AddObject(pAppModule, "Placement", pyPlacementPyType.o); - - if (PyType_Ready(&Base::RotationPy::Type) < 0) return; - union PyType_Object pyRotationPyType = {&Base::RotationPy::Type}; - PyModule_AddObject(pAppModule, "Rotation", pyRotationPyType.o); - - if (PyType_Ready(&Base::AxisPy::Type) < 0) return; - union PyType_Object pyAxisPyType = {&Base::AxisPy::Type}; - PyModule_AddObject(pAppModule, "Axis", pyAxisPyType.o); - - // Note: Create an own module 'Base' which should provide the python - // binding classes from the base module. At a later stage we should - // remove these types from the FreeCAD module. - PyObject* pBaseModule = Py_InitModule3("__FreeCADBase__", NULL, - "The Base module contains the classes for the geometric basics\n" - "like vector, matrix, bounding box, placement, rotation, axis, ..."); - Base::BaseExceptionFreeCADError = PyErr_NewException( - "Base.FreeCADError", PyExc_RuntimeError, NULL); - Py_INCREF(Base::BaseExceptionFreeCADError); - PyModule_AddObject(pBaseModule, "FreeCADError", - Base::BaseExceptionFreeCADError); - Base::Interpreter().addType(&Base::VectorPy ::Type,pBaseModule,"Vector"); - Base::Interpreter().addType(&Base::MatrixPy ::Type,pBaseModule,"Matrix"); - Base::Interpreter().addType(&Base::BoundBoxPy ::Type,pBaseModule,"BoundBox"); - Base::Interpreter().addType(&Base::PlacementPy ::Type,pBaseModule,"Placement"); - Base::Interpreter().addType(&Base::RotationPy ::Type,pBaseModule,"Rotation"); - Base::Interpreter().addType(&Base::AxisPy ::Type,pBaseModule,"Axis"); - - //insert Base and Console - Py_INCREF(pBaseModule); - PyModule_AddObject(pAppModule, "Base", pBaseModule); - Py_INCREF(pConsoleModule); - PyModule_AddObject(pAppModule, "Console", pConsoleModule); - - //insert Units module - PyObject* pUnitsModule = Py_InitModule3("Units", Base::UnitsApi::Methods, - "The Unit API"); - Base::Interpreter().addType(&Base::QuantityPy ::Type,pUnitsModule,"Quantity"); - // make sure to set the 'nb_true_divide' slot - Base::QuantityPy::Type.tp_as_number->nb_true_divide = Base::QuantityPy::Type.tp_as_number->nb_divide; - Base::Interpreter().addType(&Base::UnitPy ::Type,pUnitsModule,"Unit"); - - Py_INCREF(pUnitsModule); - PyModule_AddObject(pAppModule, "Units", pUnitsModule); - - Base::ProgressIndicatorPy::init_type(); - Base::Interpreter().addType(Base::ProgressIndicatorPy::type_object(), - pBaseModule,"ProgressIndicator"); -} - -Application::~Application() -{ -} - -//************************************************************************** -// Interface - -/// get called by the document when the name is changing -void Application::renameDocument(const char *OldName, const char *NewName) -{ - std::map::iterator pos; - pos = DocMap.find(OldName); - - if (pos != DocMap.end()) { - Document* temp; - temp = pos->second; - DocMap.erase(pos); - DocMap[NewName] = temp; - signalRenameDocument(*temp); - } - else { - throw Base::Exception("Application::renameDocument(): no document with this name to rename!"); - } -} - -Document* Application::newDocument(const char * Name, const char * UserName) -{ - // get a valid name anyway! - if (!Name || Name[0] == '\0') - Name = "Unnamed"; - string name = getUniqueDocumentName(Name); - - std::string userName; - if (UserName && UserName[0] != '\0') { - userName = UserName; - } - else { - userName = Name; - std::vector names; - names.reserve(DocMap.size()); - std::map::const_iterator pos; - for (pos = DocMap.begin();pos != DocMap.end();++pos) { - names.push_back(pos->second->Label.getValue()); - } - - if (!names.empty()) - userName = Base::Tools::getUniqueName(userName, names); - } - - // create the FreeCAD document - auto_ptr newDoc(new Document() ); - - // add the document to the internal list - DocMap[name] = newDoc.release(); // now owned by the Application - _pActiveDoc = DocMap[name]; - - - // connect the signals to the application for the new document - _pActiveDoc->signalNewObject.connect(boost::bind(&App::Application::slotNewObject, this, _1)); - _pActiveDoc->signalDeletedObject.connect(boost::bind(&App::Application::slotDeletedObject, this, _1)); - _pActiveDoc->signalChangedObject.connect(boost::bind(&App::Application::slotChangedObject, this, _1, _2)); - _pActiveDoc->signalRelabelObject.connect(boost::bind(&App::Application::slotRelabelObject, this, _1)); - _pActiveDoc->signalActivatedObject.connect(boost::bind(&App::Application::slotActivatedObject, this, _1)); - _pActiveDoc->signalUndo.connect(boost::bind(&App::Application::slotUndoDocument, this, _1)); - _pActiveDoc->signalRedo.connect(boost::bind(&App::Application::slotRedoDocument, this, _1)); - - // make sure that the active document is set in case no GUI is up - { - Base::PyGILStateLocker lock; - Py::Object active(_pActiveDoc->getPyObject(), true); - Py::Module("FreeCAD").setAttr(std::string("ActiveDocument"),active); - } - - signalNewDocument(*_pActiveDoc); - - // set the UserName after notifying all observers - _pActiveDoc->Label.setValue(userName); - - return _pActiveDoc; -} - -bool Application::closeDocument(const char* name) -{ - map::iterator pos = DocMap.find( name ); - if (pos == DocMap.end()) // no such document - return false; - - // Trigger observers before removing the document from the internal map. - // Some observers might rely on this document still being there. - signalDeleteDocument(*pos->second); - - // For exception-safety use a smart pointer - if (_pActiveDoc == pos->second) - setActiveDocument((Document*)0); - auto_ptr delDoc (pos->second); - DocMap.erase( pos ); - - // Trigger observers after removing the document from the internal map. - signalDeletedDocument(); - - return true; -} - -void Application::closeAllDocuments(void) -{ - std::map::iterator pos; - while((pos = DocMap.begin()) != DocMap.end()) - closeDocument(pos->first.c_str()); -} - -App::Document* Application::getDocument(const char *Name) const -{ - std::map::const_iterator pos; - - pos = DocMap.find(Name); - - if (pos == DocMap.end()) - return 0; - - return pos->second; -} - -const char * Application::getDocumentName(const App::Document* doc) const -{ - for (std::map::const_iterator it = DocMap.begin(); it != DocMap.end(); ++it) - if (it->second == doc) - return it->first.c_str(); - - return 0; -} - -std::vector Application::getDocuments() const -{ - std::vector docs; - for (std::map::const_iterator it = DocMap.begin(); it != DocMap.end(); ++it) - docs.push_back(it->second); - return docs; -} - -std::string Application::getUniqueDocumentName(const char *Name) const -{ - if (!Name || *Name == '\0') - return std::string(); - std::string CleanName = Base::Tools::getIdentifier(Name); - - // name in use? - std::map::const_iterator pos; - pos = DocMap.find(CleanName); - - if (pos == DocMap.end()) { - // if not, name is OK - return CleanName; - } - else { - std::vector names; - names.reserve(DocMap.size()); - for (pos = DocMap.begin();pos != DocMap.end();++pos) { - names.push_back(pos->first); - } - return Base::Tools::getUniqueName(CleanName, names); - } -} - -Document* Application::openDocument(const char * FileName) -{ - FileInfo File(FileName); - - if (!File.exists()) { - std::stringstream str; - str << "File '" << FileName << "' does not exist!"; - throw Base::Exception(str.str().c_str()); - } - - // Before creating a new document we check whether the document is already open - std::string filepath = File.filePath(); - for (std::map::iterator it = DocMap.begin(); it != DocMap.end(); ++it) { - // get unique path separators - std::string fi = FileInfo(it->second->FileName.getValue()).filePath(); - if (filepath == fi) { - std::stringstream str; - str << "The project '" << FileName << "' is already open!"; - throw Base::Exception(str.str().c_str()); - } - } - - // Use the same name for the internal and user name. - // The file name is UTF-8 encoded which means that the internal name will be modified - // to only contain valid ASCII characters but the user name will be kept. - Document* newDoc = newDocument(File.fileNamePure().c_str(), File.fileNamePure().c_str()); - - newDoc->FileName.setValue(File.filePath()); - - // read the document - newDoc->restore(); - - return newDoc; -} - -Document* Application::getActiveDocument(void) const -{ - return _pActiveDoc; -} - -void Application::setActiveDocument(Document* pDoc) -{ - _pActiveDoc = pDoc; - - // make sure that the active document is set in case no GUI is up - if (pDoc) { - Base::PyGILStateLocker lock; - Py::Object active(pDoc->getPyObject(), true); - Py::Module("FreeCAD").setAttr(std::string("ActiveDocument"),active); - } - else { - Base::PyGILStateLocker lock; - Py::Module("FreeCAD").setAttr(std::string("ActiveDocument"),Py::None()); - } - - if (pDoc) - signalActiveDocument(*pDoc); -} - -void Application::setActiveDocument(const char *Name) -{ - // If no active document is set, resort to a default. - if (*Name == '\0') { - _pActiveDoc = 0; - return; - } - - std::map::iterator pos; - pos = DocMap.find(Name); - - if (pos != DocMap.end()) { - setActiveDocument(pos->second); - } - else { - std::stringstream s; - s << "Try to activate unknown document '" << Name << "'"; - throw Base::Exception(s.str()); - } -} - -const char* Application::getHomePath(void) const -{ - return _mConfig["AppHomePath"].c_str(); -} - -const char* Application::getExecutableName(void) const -{ - return _mConfig["ExeName"].c_str(); -} - -std::string Application::getTempPath() -{ - return mConfig["AppTempPath"]; -} - -std::string Application::getTempFileName(const char* FileName) -{ - return Base::FileInfo::getTempFileName(FileName, getTempPath().c_str()); -} - -std::string Application::getUserAppDataDir() -{ - return mConfig["UserAppData"]; -} - -std::string Application::getUserMacroDir() -{ - std::string path("Macro/"); - return mConfig["UserAppData"] + path; -} - -std::string Application::getResourceDir() -{ -#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 -} - -std::string Application::getHelpDir() -{ -#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 -} - -ParameterManager & Application::GetSystemParameter(void) -{ - return *_pcSysParamMngr; -} - -ParameterManager & Application::GetUserParameter(void) -{ - return *_pcUserParamMngr; -} - -ParameterManager * Application::GetParameterSet(const char* sName) const -{ - std::map::const_iterator it = mpcPramManager.find(sName); - if ( it != mpcPramManager.end() ) - return it->second; - else - return 0; -} - -const std::map & Application::GetParameterSetList(void) const -{ - return mpcPramManager; -} - -void Application::AddParameterSet(const char* sName) -{ - std::map::const_iterator it = mpcPramManager.find(sName); - if ( it != mpcPramManager.end() ) - return; - mpcPramManager[sName] = new ParameterManager(); -} - -void Application::RemoveParameterSet(const char* sName) -{ - std::map::iterator it = mpcPramManager.find(sName); - // Must not delete user or system parameter - if ( it == mpcPramManager.end() || it->second == _pcUserParamMngr || it->second == _pcSysParamMngr ) - return; - delete it->second; - mpcPramManager.erase(it); -} - -Base::Reference Application::GetParameterGroupByPath(const char* sName) -{ - std::string cName = sName,cTemp; - - std::string::size_type pos = cName.find(':'); - - // is there a path seperator ? - if (pos == std::string::npos) { - throw Base::Exception("Application::GetParameterGroupByPath() no parameter set name specified"); - } - // assigning the parameter set name - cTemp.assign(cName,0,pos); - cName.erase(0,pos+1); - - // test if name is valid - std::map::iterator It = mpcPramManager.find(cTemp.c_str()); - if (It == mpcPramManager.end()) - throw Base::Exception("Application::GetParameterGroupByPath() unknown parameter set name specified"); - - return It->second->GetGroup(cName.c_str()); -} - -void Application::addImportType(const char* Type, const char* ModuleName) -{ - FileTypeItem item; - item.filter = Type; - item.module = ModuleName; - - // Extract each filetype from 'Type' literal - std::string::size_type pos = item.filter.find("*."); - while ( pos != std::string::npos ) { - std::string::size_type next = item.filter.find_first_of(" )", pos+1); - std::string::size_type len = next-pos-2; - std::string type = item.filter.substr(pos+2,len); - item.types.push_back(type); - pos = item.filter.find("*.", next); - } - - // Due to branding stuff replace "FreeCAD" with the branded application name - if (strncmp(Type, "FreeCAD", 7) == 0) { - std::string AppName = Config()["ExeName"]; - AppName += item.filter.substr(7); - item.filter = AppName; - // put to the front of the array - _mImportTypes.insert(_mImportTypes.begin(),item); - } - else { - _mImportTypes.push_back(item); - } -} - -std::vector Application::getImportModules(const char* Type) const -{ - std::vector modules; - for (std::vector::const_iterator it = _mImportTypes.begin(); it != _mImportTypes.end(); ++it) { - const std::vector& types = it->types; - for (std::vector::const_iterator jt = types.begin(); jt != types.end(); ++jt) { -#ifdef __GNUC__ - if (strcasecmp(Type,jt->c_str()) == 0) -#else - if (_stricmp(Type,jt->c_str()) == 0) -#endif - modules.push_back(it->module); - } - } - - return modules; -} - -std::vector Application::getImportModules() const -{ - std::vector modules; - for (std::vector::const_iterator it = _mImportTypes.begin(); it != _mImportTypes.end(); ++it) - modules.push_back(it->module); - std::sort(modules.begin(), modules.end()); - modules.erase(std::unique(modules.begin(), modules.end()), modules.end()); - return modules; -} - -std::vector Application::getImportTypes(const char* Module) const -{ - std::vector types; - for (std::vector::const_iterator it = _mImportTypes.begin(); it != _mImportTypes.end(); ++it) { -#ifdef __GNUC__ - if (strcasecmp(Module,it->module.c_str()) == 0) -#else - if (_stricmp(Module,it->module.c_str()) == 0) -#endif - types.insert(types.end(), it->types.begin(), it->types.end()); - } - - return types; -} - -std::vector Application::getImportTypes(void) const -{ - std::vector types; - for (std::vector::const_iterator it = _mImportTypes.begin(); it != _mImportTypes.end(); ++it) { - types.insert(types.end(), it->types.begin(), it->types.end()); - } - - std::sort(types.begin(), types.end()); - types.erase(std::unique(types.begin(), types.end()), types.end()); - - return types; -} - -std::map Application::getImportFilters(const char* Type) const -{ - std::map moduleFilter; - for (std::vector::const_iterator it = _mImportTypes.begin(); it != _mImportTypes.end(); ++it) { - const std::vector& types = it->types; - for (std::vector::const_iterator jt = types.begin(); jt != types.end(); ++jt) { -#ifdef __GNUC__ - if (strcasecmp(Type,jt->c_str()) == 0) -#else - if (_stricmp(Type,jt->c_str()) == 0) -#endif - moduleFilter[it->filter] = it->module; - } - } - - return moduleFilter; -} - -std::map Application::getImportFilters(void) const -{ - std::map filter; - for (std::vector::const_iterator it = _mImportTypes.begin(); it != _mImportTypes.end(); ++it) { - filter[it->filter] = it->module; - } - - return filter; -} - -void Application::addExportType(const char* Type, const char* ModuleName) -{ - FileTypeItem item; - item.filter = Type; - item.module = ModuleName; - - // Extract each filetype from 'Type' literal - std::string::size_type pos = item.filter.find("*."); - while ( pos != std::string::npos ) { - std::string::size_type next = item.filter.find_first_of(" )", pos+1); - std::string::size_type len = next-pos-2; - std::string type = item.filter.substr(pos+2,len); - item.types.push_back(type); - pos = item.filter.find("*.", next); - } - - // Due to branding stuff replace "FreeCAD" with the branded application name - if (strncmp(Type, "FreeCAD", 7) == 0) { - std::string AppName = Config()["ExeName"]; - AppName += item.filter.substr(7); - item.filter = AppName; - // put to the front of the array - _mExportTypes.insert(_mExportTypes.begin(),item); - } - else { - _mExportTypes.push_back(item); - } -} - -std::vector Application::getExportModules(const char* Type) const -{ - std::vector modules; - for (std::vector::const_iterator it = _mExportTypes.begin(); it != _mExportTypes.end(); ++it) { - const std::vector& types = it->types; - for (std::vector::const_iterator jt = types.begin(); jt != types.end(); ++jt) { -#ifdef __GNUC__ - if (strcasecmp(Type,jt->c_str()) == 0) -#else - if (_stricmp(Type,jt->c_str()) == 0) -#endif - modules.push_back(it->module); - } - } - - return modules; -} - -std::vector Application::getExportModules() const -{ - std::vector modules; - for (std::vector::const_iterator it = _mExportTypes.begin(); it != _mExportTypes.end(); ++it) - modules.push_back(it->module); - std::sort(modules.begin(), modules.end()); - modules.erase(std::unique(modules.begin(), modules.end()), modules.end()); - return modules; -} - -std::vector Application::getExportTypes(const char* Module) const -{ - std::vector types; - for (std::vector::const_iterator it = _mExportTypes.begin(); it != _mExportTypes.end(); ++it) { -#ifdef __GNUC__ - if (strcasecmp(Module,it->module.c_str()) == 0) -#else - if (_stricmp(Module,it->module.c_str()) == 0) -#endif - types.insert(types.end(), it->types.begin(), it->types.end()); - } - - return types; -} - -std::vector Application::getExportTypes(void) const -{ - std::vector types; - for (std::vector::const_iterator it = _mExportTypes.begin(); it != _mExportTypes.end(); ++it) { - types.insert(types.end(), it->types.begin(), it->types.end()); - } - - std::sort(types.begin(), types.end()); - types.erase(std::unique(types.begin(), types.end()), types.end()); - - return types; -} - -std::map Application::getExportFilters(const char* Type) const -{ - std::map moduleFilter; - for (std::vector::const_iterator it = _mExportTypes.begin(); it != _mExportTypes.end(); ++it) { - const std::vector& types = it->types; - for (std::vector::const_iterator jt = types.begin(); jt != types.end(); ++jt) { -#ifdef __GNUC__ - if (strcasecmp(Type,jt->c_str()) == 0) -#else - if (_stricmp(Type,jt->c_str()) == 0) -#endif - moduleFilter[it->filter] = it->module; - } - } - - return moduleFilter; -} - -std::map Application::getExportFilters(void) const -{ - std::map filter; - for (std::vector::const_iterator it = _mExportTypes.begin(); it != _mExportTypes.end(); ++it) { - filter[it->filter] = it->module; - } - - return filter; -} - -//************************************************************************** -// signaling -void Application::slotNewObject(const App::DocumentObject&O) -{ - this->signalNewObject(O); -} - -void Application::slotDeletedObject(const App::DocumentObject&O) -{ - this->signalDeletedObject(O); -} - -void Application::slotChangedObject(const App::DocumentObject&O, const App::Property& P) -{ - this->signalChangedObject(O,P); -} - -void Application::slotRelabelObject(const App::DocumentObject&O) -{ - this->signalRelabelObject(O); -} - -void Application::slotActivatedObject(const App::DocumentObject&O) -{ - this->signalActivatedObject(O); -} - -void Application::slotUndoDocument(const App::Document& d) -{ - this->signalUndoDocument(d); -} - -void Application::slotRedoDocument(const App::Document& d) -{ - this->signalRedoDocument(d); -} - -//************************************************************************** -// Init, Destruct and singleton - -Application * Application::_pcSingleton = 0; - -int Application::_argc; -char ** Application::_argv; - - -void Application::destruct(void) -{ - // saving system parameter - Console().Log("Saving system parameter...\n"); - _pcSysParamMngr->SaveDocument(mConfig["SystemParameter"].c_str()); - // saving the User parameter - Console().Log("Saving system parameter...done\n"); - Console().Log("Saving user parameter...\n"); - _pcUserParamMngr->SaveDocument(mConfig["UserParameter"].c_str()); - Console().Log("Saving user parameter...done\n"); - // clean up - delete _pcSysParamMngr; - delete _pcUserParamMngr; - - // not initialized or doubel destruct! - assert(_pcSingleton); - delete _pcSingleton; - - // We must detach from console and delete the observer to save our file - destructObserver(); - - Base::Interpreter().finalize(); - - ScriptFactorySingleton::Destruct(); - InterpreterSingleton::Destruct(); - Base::Type::destruct(); -} - -void Application::destructObserver(void) -{ - if ( _pConsoleObserverFile ) { - Console().DetachObserver(_pConsoleObserverFile); - delete _pConsoleObserverFile; - _pConsoleObserverFile = 0; - } - if ( _pConsoleObserverStd ) { - Console().DetachObserver(_pConsoleObserverStd); - delete _pConsoleObserverStd; - _pConsoleObserverStd = 0; - } -} - -/** freecadNewHandler() - * prints an error message and throws an exception - */ -#ifdef _MSC_VER // New handler for Microsoft Visual C++ compiler -int __cdecl freecadNewHandler(size_t size ) -{ - // throw an exception - throw Base::MemoryException(); - return 0; -} -#else // Ansi C/C++ new handler -static void freecadNewHandler () -{ - // throw an exception - throw Base::MemoryException(); -} -#endif - -void segmentation_fault_handler(int sig) -{ - switch (sig) { - case SIGSEGV: - std::cerr << "Illegal storage access..." << std::endl; -#if !defined(_DEBUG) - throw Base::Exception("Illegal storage access! Please save your work under a new file name and restart the application!"); -#endif - break; - case SIGABRT: - std::cerr << "Abnormal program termination..." << std::endl; -#if !defined(_DEBUG) - throw Base::Exception("Break signal occoured"); -#endif - break; - default: - std::cerr << "Unknown error occurred..." << std::endl; - break; - } -} - -void my_terminate_handler() -{ - std::cerr << "Terminating..." << std::endl; -} - -void unexpection_error_handler() -{ - std::cerr << "Unexpected error occurred..." << std::endl; - // try to throw an exception and give the user chance to save their work -#if !defined(_DEBUG) - throw Base::Exception("Unexpected error occurred! Please save your work under a new file name and restart the application!"); -#endif - - terminate(); -} - -#ifdef _MSC_VER // Microsoft compiler - -void my_trans_func( unsigned int code, EXCEPTION_POINTERS* pExp ) -{ - - //switch (code) - //{ - // case FLT_DIVIDE_BY_ZERO : - // //throw CMyFunkyDivideByZeroException(code, pExp); - // throw Base::Exception("Devision by zero!"); - // break; - //} - - // general C++ SEH exception for things we don't need to handle separately.... - throw Base::Exception("my_trans_func()"); -} -#endif -void Application::init(int argc, char ** argv) -{ - try { - // install our own new handler -#ifdef _MSC_VER // Microsoft compiler - _set_new_handler ( freecadNewHandler ); // Setup new handler - _set_new_mode( 1 ); // Re-route malloc failures to new handler ! -#else // Ansi compiler - std::set_new_handler (freecadNewHandler); // ANSI new handler -#endif - // if an unexpected crash occurs we can install a handler function to - // write some additional information -#ifdef _MSC_VER // Microsoft compiler - std::signal(SIGSEGV,segmentation_fault_handler); - std::signal(SIGABRT,segmentation_fault_handler); - std::set_terminate(my_terminate_handler); - std::set_unexpected(unexpection_error_handler); -// _set_se_translator(my_trans_func); -#endif - - initTypes(); - -#if (BOOST_VERSION < 104600) || (BOOST_FILESYSTEM_VERSION == 2) - boost::filesystem::path::default_name_check(boost::filesystem::no_check); -#endif - - initConfig(argc,argv); - initApplication(); - } - catch (...) { - // force the log to flush - destructObserver(); - throw; - } -} - -void Application::initTypes(void) -{ - // Base types - Base::Type ::init(); - Base::BaseClass ::init(); - Base::Exception ::init(); - Base::Persistence ::init(); - - // Complex data classes - Data::ComplexGeoData ::init(); - Data::Segment ::init(); - - // Properties - App ::Property ::init(); - App ::PropertyContainer ::init(); - App ::PropertyLists ::init(); - App ::PropertyBool ::init(); - App ::PropertyBoolList ::init(); - App ::PropertyFloat ::init(); - App ::PropertyFloatList ::init(); - App ::PropertyFloatConstraint ::init(); - App ::PropertyQuantity ::init(); - App ::PropertyQuantityConstraint::init(); - App ::PropertyAngle ::init(); - App ::PropertyDistance ::init(); - App ::PropertyLength ::init(); - App ::PropertySpeed ::init(); - App ::PropertyAcceleration ::init(); - App ::PropertyForce ::init(); - App ::PropertyPressure ::init(); - App ::PropertyInteger ::init(); - App ::PropertyIntegerConstraint ::init(); - App ::PropertyPercent ::init(); - App ::PropertyEnumeration ::init(); - App ::PropertyIntegerList ::init(); - App ::PropertyIntegerSet ::init(); - App ::PropertyMap ::init(); - App ::PropertyString ::init(); - App ::PropertyUUID ::init(); - App ::PropertyFont ::init(); - App ::PropertyStringList ::init(); - App ::PropertyLink ::init(); - App ::PropertyLinkSub ::init(); - App ::PropertyLinkList ::init(); - App ::PropertyLinkSubList ::init(); - App ::PropertyMatrix ::init(); - App ::PropertyVector ::init(); - App ::PropertyVectorDistance ::init(); - App ::PropertyVectorList ::init(); - App ::PropertyPlacement ::init(); - App ::PropertyPlacementLink ::init(); - App ::PropertyGeometry ::init(); - App ::PropertyComplexGeoData ::init(); - App ::PropertyColor ::init(); - App ::PropertyColorList ::init(); - App ::PropertyMaterial ::init(); - App ::PropertyPath ::init(); - App ::PropertyFile ::init(); - App ::PropertyFileIncluded ::init(); - App ::PropertyPythonObject ::init(); - App ::PropertyExpressionEngine ::init(); - - // Document classes - App ::DocumentObject ::init(); - App ::GeoFeature ::init(); - App ::FeatureTest ::init(); - App ::FeatureTestException ::init(); - App ::FeaturePython ::init(); - App ::GeometryPython ::init(); - App ::Document ::init(); - App ::DocumentObjectGroup ::init(); - App ::DocumentObjectGroupPython ::init(); - App ::DocumentObjectFileIncluded::init(); - App ::InventorObject ::init(); - App ::VRMLObject ::init(); - App ::Annotation ::init(); - App ::AnnotationLabel ::init(); - App ::MeasureDistance ::init(); - App ::MaterialObject ::init(); - App ::MaterialObjectPython ::init(); - App ::Placement ::init(); - App ::Plane ::init(); - - // Expression classes - App ::Expression ::init(); - App ::UnitExpression ::init(); - App ::NumberExpression ::init(); - App ::ConstantExpression ::init(); - App ::OperatorExpression ::init(); - App ::VariableExpression ::init(); - App ::ConditionalExpression ::init(); - App ::StringExpression ::init(); - App ::FunctionExpression ::init(); - -} - -void Application::initConfig(int argc, char ** argv) -{ - // find the home path.... - mConfig["AppHomePath"] = FindHomePath(argv[0]); - - // Version of the application extracted from SubWCRef into src/Build/Version.h - // We only set these keys if not yet defined. Therefore it suffices to search - // only for 'BuildVersionMajor'. - if (App::Application::Config().find("BuildVersionMajor") == App::Application::Config().end()) { - std::stringstream str; str << FCVersionMajor << "." << FCVersionMinor; - App::Application::Config()["ExeVersion" ] = str.str(); - App::Application::Config()["BuildVersionMajor" ] = FCVersionMajor; - App::Application::Config()["BuildVersionMinor" ] = FCVersionMinor; - App::Application::Config()["BuildRevision" ] = FCRevision; - App::Application::Config()["BuildRepositoryURL" ] = FCRepositoryURL; - App::Application::Config()["BuildRevisionDate" ] = FCRevisionDate; -#if defined(FCRepositoryHash) - App::Application::Config()["BuildRevisionHash" ] = FCRepositoryHash; -#endif -#if defined(FCRepositoryBranch) - App::Application::Config()["BuildRevisionBranch"] = FCRepositoryBranch; -#endif - } - - _argc = argc; - _argv = argv; - - // Now it's time to read-in the file branding.xml if it exists - Branding brand; - QString binDir = QString::fromUtf8((mConfig["AppHomePath"] + "bin").c_str()); - QFileInfo fi(binDir, QString::fromLatin1("branding.xml")); - if (brand.readFile(fi.absoluteFilePath())) { - Branding::XmlConfig cfg = brand.getUserDefines(); - for (Branding::XmlConfig::iterator it = cfg.begin(); it != cfg.end(); ++it) { - App::Application::Config()[it.key()] = it.value(); - } - } - - // extract home paths - ExtractUserPath(); - -# ifdef FC_DEBUG - mConfig["Debug"] = "1"; -# else - mConfig["Debug"] = "0"; -# endif - - // init python - mConfig["PythonSearchPath"] = Interpreter().init(argc,argv); - - // Parse the options which have impact to the init process - ParseOptions(argc,argv); - - // Init console =========================================================== - Base::PyGILStateLocker lock; - _pConsoleObserverStd = new ConsoleObserverStd(); - Console().AttachObserver(_pConsoleObserverStd); - if (mConfig["Verbose"] == "Strict") - Console().SetMode(ConsoleSingleton::Verbose); - - // file logging Init =========================================================== - if (mConfig["LoggingFile"] == "1") { - _pConsoleObserverFile = new ConsoleObserverFile(mConfig["LoggingFileName"].c_str()); - Console().AttachObserver(_pConsoleObserverFile); - } - else - _pConsoleObserverFile = 0; - - // Banner =========================================================== - if (!(mConfig["Verbose"] == "Strict")) - Console().Message("%s %s, Libs: %s.%sR%s\n%s",mConfig["ExeName"].c_str(), - mConfig["ExeVersion"].c_str(), - mConfig["BuildVersionMajor"].c_str(), - mConfig["BuildVersionMinor"].c_str(), - mConfig["BuildRevision"].c_str(), - mConfig["CopyrightInfo"].c_str()); - else - Console().Message("%s %s, Libs: %s.%sB%s\n",mConfig["ExeName"].c_str(), - mConfig["ExeVersion"].c_str(), - mConfig["BuildVersionMajor"].c_str(), - mConfig["BuildVersionMinor"].c_str(), - mConfig["BuildRevision"].c_str()); - - LoadParameters(); - - // Set application tmp. directory - mConfig["AppTempPath"] = Base::FileInfo::getTempPath(); - std::string tmpPath = _pcUserParamMngr->GetGroup("BaseApp/Preferences/General")->GetASCII("TempPath"); - Base::FileInfo di(tmpPath); - if (di.exists() && di.isDir()) { - mConfig["AppTempPath"] = tmpPath + "/"; - } - - - // capture python variables - SaveEnv("PYTHONPATH"); - SaveEnv("PYTHONHOME"); - SaveEnv("TCL_LIBRARY"); - SaveEnv("TCLLIBPATH"); - - // capture CasCade variables - SaveEnv("CSF_MDTVFontDirectory"); - SaveEnv("CSF_MDTVTexturesDirectory"); - SaveEnv("CSF_UnitsDefinition"); - SaveEnv("CSF_UnitsLexicon"); - SaveEnv("CSF_StandardDefaults"); - SaveEnv("CSF_PluginDefaults"); - SaveEnv("CSF_LANGUAGE"); - SaveEnv("CSF_SHMessage"); - SaveEnv("CSF_XCAFDefaults"); - SaveEnv("CSF_GraphicShr"); - SaveEnv("CSF_IGESDefaults"); - SaveEnv("CSF_STEPDefaults"); - - // capture path - SaveEnv("PATH"); - logStatus(); -} - -void Application::SaveEnv(const char* s) -{ - char *c = getenv(s); - if (c) - mConfig[s] = c; -} - -void Application::initApplication(void) -{ - // interpreter and Init script ========================================================== - // register scripts - new ScriptProducer( "FreeCADInit", FreeCADInit ); - new ScriptProducer( "FreeCADTest", FreeCADTest ); - - // creating the application - if (!(mConfig["Verbose"] == "Strict")) Console().Log("Create Application\n"); - Application::_pcSingleton = new Application(0,0,mConfig); - - // set up Unit system default - ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath - ("User parameter:BaseApp/Preferences/Units"); - UnitsApi::setSchema((UnitSystem)hGrp->GetInt("UserSchema",0)); - -#if defined (_DEBUG) - Console().Log("Application is built with debug information\n"); -#endif - - // starting the init script - Console().Log("Run App init script\n"); - Interpreter().runString(Base::ScriptFactory().ProduceScript("FreeCADInit")); -} - -std::list Application::getCmdLineFiles() -{ - std::list files; - - // cycling through all the open files - unsigned short count = 0; - count = atoi(mConfig["OpenFileCount"].c_str()); - std::string File; - - for (unsigned short i=0; i& files) -{ - Base::Console().Log("Init: Processing command line files\n"); - for (std::list::const_iterator it = files.begin(); it != files.end(); ++it) { - Base::FileInfo file(*it); - - Base::Console().Log("Init: Processing file: %s\n",file.filePath().c_str()); - - try { - if (file.hasExtension("fcstd") || file.hasExtension("std")) { - // try to open - Application::_pcSingleton->openDocument(file.filePath().c_str()); - } - else if (file.hasExtension("fcscript") || file.hasExtension("fcmacro")) { - Base::Interpreter().runFile(file.filePath().c_str(), true); - } -<<<<<<< d9efca578bac2e53f02f6d1807be05cf950b405f - else if (file.hasExtension("py")) { - try { - Base::Interpreter().loadModule(file.fileNamePure().c_str()); -======= - else if (File.hasExtension("py")) { - try{ - Base::Interpreter().loadModule(File.fileNamePure().c_str()); ->>>>>>> Run arbitrary scripts from Cmd command line - } - catch(const PyException&) { - // if loading the module does not work, try just running the script (run in __main__) - Base::Interpreter().runFile(file.filePath().c_str(),true); - } - } - else { - std::string ext = file.extension(); - std::vector mods = App::GetApplication().getImportModules(ext.c_str()); - if (!mods.empty()) { - std::string escapedstr = Base::Tools::escapedUnicodeFromUtf8(file.filePath().c_str()); - Base::Interpreter().loadModule(mods.front().c_str()); - Base::Interpreter().runStringArg("import %s",mods.front().c_str()); - Base::Interpreter().runStringArg("%s.open(u\"%s\")",mods.front().c_str(), - escapedstr.c_str()); - Base::Console().Log("Command line open: %s.open(u\"%s\")\n",mods.front().c_str(),escapedstr.c_str()); - } - else { - Console().Warning("File format not supported: %s \n", file.filePath().c_str()); - } - } - } - catch (const Base::SystemExitException&) { - throw; // re-throw to main() function - } - catch (const Base::Exception& e) { - Console().Error("Exception while processing file: %s [%s]\n", file.filePath().c_str(), e.what()); - } - catch (...) { - Console().Error("Unknown exception while processing file: %s \n", file.filePath().c_str()); - } - } -} - -void Application::processCmdLineFiles(void) -{ - // process files passed to command line - std::list files = getCmdLineFiles(); - processFiles(files); - - if (files.empty()) { - if (mConfig["RunMode"] == "Exit") - mConfig["RunMode"] = "Cmd"; - } - - const std::map& cfg = Application::Config(); - std::map::const_iterator it = cfg.find("SaveFile"); - if (it != cfg.end()) { - std::string output = it->second; - Base::FileInfo fi(output); - std::string ext = fi.extension(); - try { - std::vector mods = App::GetApplication().getExportModules(ext.c_str()); - if (!mods.empty()) { - Base::Interpreter().loadModule(mods.front().c_str()); - Base::Interpreter().runStringArg("import %s",mods.front().c_str()); - Base::Interpreter().runStringArg("%s.export(App.ActiveDocument.Objects, '%s')" - ,mods.front().c_str(),output.c_str()); - } - else { - Console().Warning("File format not supported: %s \n", output.c_str()); - } - } - catch (const Base::Exception& e) { - Console().Error("Exception while saving to file: %s [%s]\n", output.c_str(), e.what()); - } - catch (...) { - Console().Error("Unknown exception while saving to file: %s \n", output.c_str()); - } - } -} - -void Application::runApplication() -{ - // process all files given through command line interface - processCmdLineFiles(); - - if (mConfig["RunMode"] == "Cmd") { - // Run the comandline interface - Interpreter().runCommandLine("FreeCAD Console mode"); - } - else if (mConfig["RunMode"] == "Internal") { - // run internal script - Console().Log("Running internal script:\n"); - Interpreter().runString(Base::ScriptFactory().ProduceScript(mConfig["ScriptFileName"].c_str())); - } - else if (mConfig["RunMode"] == "Exit") { - // geting out - Console().Log("Exiting on purpose\n"); - } - else { - Console().Log("Unknown Run mode (%d) in main()?!?\n\n",mConfig["RunMode"].c_str()); - } -} - -void Application::logStatus() -{ - time_t now; - time(&now); - Console().Log("Time = %s", ctime(&now)); - - for (std::map::iterator It = mConfig.begin();It!= mConfig.end();++It) { - Console().Log("%s = %s\n",It->first.c_str(),It->second.c_str()); - } -} - -void Application::LoadParameters(void) -{ - // create standard parameter sets - _pcSysParamMngr = new ParameterManager(); - _pcUserParamMngr = new ParameterManager(); - - // Init parameter sets =========================================================== - // - if (mConfig.find("UserParameter") == mConfig.end()) - mConfig["UserParameter"] = mConfig["UserAppData"] + "user.cfg"; - if (mConfig.find("SystemParameter") == mConfig.end()) - mConfig["SystemParameter"] = mConfig["UserAppData"] + "system.cfg"; - - - try { - if (_pcSysParamMngr->LoadOrCreateDocument(mConfig["SystemParameter"].c_str()) && !(mConfig["Verbose"] == "Strict")) { - // Configuration file optional when using as Python module - if (!Py_IsInitialized()) { - Console().Warning(" Parameter does not exist, writing initial one\n"); - Console().Message(" This warning normally means that FreeCAD is running for the first time\n" - " or the configuration was deleted or moved. FreeCAD is generating the standard\n" - " configuration.\n"); - } - } - } - catch (const Base::Exception& e) { - // try to proceed with an empty XML document - Base::Console().Error("%s in file %s.\n" - "Continue with an empty configuration.\n", - e.what(), mConfig["SystemParameter"].c_str()); - _pcSysParamMngr->CreateDocument(); - } - - try { - if (_pcUserParamMngr->LoadOrCreateDocument(mConfig["UserParameter"].c_str()) && !(mConfig["Verbose"] == "Strict")) { - // The user parameter file doesn't exist. When an alternative parameter file is offered - // this will be used. - std::map::iterator it = mConfig.find("UserParameterTemplate"); - if (it != mConfig.end()) { - QString path = QString::fromUtf8(it->second.c_str()); - if (QDir(path).isRelative()) { - QString home = QString::fromUtf8(mConfig["AppHomePath"].c_str()); - path = QFileInfo(QDir(home), path).absoluteFilePath(); - } - QFileInfo fi(path); - if (fi.exists()) { - _pcUserParamMngr->LoadDocument(path.toUtf8().constData()); - } - } - - // Configuration file optional when using as Python module - if (!Py_IsInitialized()) { - Console().Warning(" User settings do not exist, writing initial one\n"); - Console().Message(" This warning normally means that FreeCAD is running for the first time\n" - " or your configuration was deleted or moved. The system defaults\n" - " will be automatically generated for you.\n"); - } - } - } - catch (const Base::Exception& e) { - // try to proceed with an empty XML document - Base::Console().Error("%s in file %s.\n" - "Continue with an empty configuration.\n", - e.what(), mConfig["UserParameter"].c_str()); - _pcUserParamMngr->CreateDocument(); - } -} - - -#if defined(_MSC_VER) -// fix weird error while linking boost (all versions of VC) -// VS2010: http://forum.freecadweb.org/viewtopic.php?f=4&t=1886&p=12553&hilit=boost%3A%3Afilesystem%3A%3Aget#p12553 -namespace boost { namespace program_options { std::string arg="arg"; } } -#if (defined (BOOST_VERSION) && (BOOST_VERSION >= 104100)) -namespace boost { namespace program_options { - const unsigned options_description::m_default_line_length = 80; -} } -#endif -#endif - -#if 0 // it seems that SUSE has fixed the broken boost package -// reported for SUSE in issue #0000208 -#if defined(__GNUC__) -#if BOOST_VERSION == 104400 -namespace boost { namespace filesystem { - bool no_check( const std::string & ) { return true; } -} } -#endif -#endif -#endif - -pair customSyntax(const string& s) -{ -#if defined(FC_OS_MACOSX) - if (s.find("-psn_") == 0) - return make_pair(string("psn"), s.substr(5)); -#endif - if (s.find("-display") == 0) - return make_pair(string("display"), string("null")); - else if (s.find("-style") == 0) - return make_pair(string("style"), string("null")); - else if (s.find("-geometry") == 0) - return make_pair(string("geometry"), string("null")); - else if (s.find("-font") == 0) - return make_pair(string("font"), string("null")); - else if (s.find("-fn") == 0) - return make_pair(string("fn"), string("null")); - else if (s.find("-background") == 0) - return make_pair(string("background"), string("null")); - else if (s.find("-bg") == 0) - return make_pair(string("bg"), string("null")); - else if (s.find("-foreground") == 0) - return make_pair(string("foreground"), string("null")); - else if (s.find("-fg") == 0) - return make_pair(string("fg"), string("null")); - else if (s.find("-button") == 0) - return make_pair(string("button"), string("null")); - else if (s.find("-btn") == 0) - return make_pair(string("btn"), string("null")); - else if (s.find("-name") == 0) - return make_pair(string("name"), string("null")); - else if (s.find("-title") == 0) - return make_pair(string("title"), string("null")); - else if (s.find("-visual") == 0) - return make_pair(string("visual"), string("null")); -// else if (s.find("-ncols") == 0) -// return make_pair(string("ncols"), boost::program_options::value(1)); -// else if (s.find("-cmap") == 0) -// return make_pair(string("cmap"), string("null")); - else if ('@' == s[0]) - return std::make_pair(string("response-file"), s.substr(1)); - else - return make_pair(string(), string()); - -} - -// A helper function to simplify the main part. -template -ostream& operator<<(ostream& os, const vector& v) -{ - copy(v.begin(), v.end(), ostream_iterator(cout, " ")); - return os; -} - -void Application::ParseOptions(int ac, char ** av) -{ - // Declare a group of options that will be - // allowed only on the command line - options_description generic("Generic options"); - generic.add_options() - ("version,v", "Prints version string") - ("help,h", "Prints help message") - ("console,c", "Starts in console mode") - ("response-file", value(),"Can be specified with '@name', too") - ("dump-config", "Dumps configuration") - ("get-config", value(), "Prints the value of the requested configuration key") - ; - - // Declare a group of options that will be - // allowed both on the command line and in - // the config file - std::string descr("Writes a log file to:\n"); - descr += mConfig["UserAppData"]; - descr += mConfig["ExeName"]; - descr += ".log"; - boost::program_options::options_description config("Configuration"); - config.add_options() - //("write-log,l", value(), "write a log file") - ("write-log,l", descr.c_str()) - ("log-file", value(), "Unlike to --write-log this allows to log to an arbitrary file") - ("user-cfg,u", value(),"User config file to load/save user settings") - ("system-cfg,s", value(),"Systen config file to load/save system settings") - ("run-test,t", value() ,"Test level") - ("module-path,M", value< vector >()->composing(),"Additional module paths") - ("python-path,P", value< vector >()->composing(),"Additional python paths") - ("single-instance", "Allow to run a single instance of the application") - ; - - - // Hidden options, will be allowed both on the command line and - // in the config file, but will not be shown to the user. - boost::program_options::options_description hidden("Hidden options"); - hidden.add_options() - ("input-file", boost::program_options::value< vector >(), "input file") - ("output", boost::program_options::value(),"output file") - ("hidden", "don't show the main window") - // this are to ignore for the window system (QApplication) - ("style", boost::program_options::value< string >(), "set the application GUI style") - ("stylesheet", boost::program_options::value< string >(), "set the application stylesheet") - ("session", boost::program_options::value< string >(), "restore the application from an earlier session") - ("reverse", "set the application's layout direction from right to left") - ("display", boost::program_options::value< string >(), "set the X-Server") - ("geometry ", boost::program_options::value< string >(), "set the X-Window geometry") - ("font", boost::program_options::value< string >(), "set the X-Window font") - ("fn", boost::program_options::value< string >(), "set the X-Window font") - ("background", boost::program_options::value< string >(), "set the X-Window background color") - ("bg", boost::program_options::value< string >(), "set the X-Window background color") - ("foreground", boost::program_options::value< string >(), "set the X-Window foreground color") - ("fg", boost::program_options::value< string >(), "set the X-Window foreground color") - ("button", boost::program_options::value< string >(), "set the X-Window button color") - ("btn", boost::program_options::value< string >(), "set the X-Window button color") - ("name", boost::program_options::value< string >(), "set the X-Window name") - ("title", boost::program_options::value< string >(), "set the X-Window title") - ("visual", boost::program_options::value< string >(), "set the X-Window to color scema") - ("ncols", boost::program_options::value< int >(), "set the X-Window to color scema") - ("cmap", "set the X-Window to color scema") -#if defined(FC_OS_MACOSX) - ("psn", boost::program_options::value< string >(), "process serial number") -#endif - ; - - // Ignored options, will be safely ignored. Mostly used by underlaying libs. - //boost::program_options::options_description x11("X11 options"); - //x11.add_options() - // ("display", boost::program_options::value< string >(), "set the X-Server") - // ; - //0000723: improper handling of qt specific comand line arguments - std::vector args; - bool merge=false; - for (int i=1; i().c_str()); - if (!ifs) { - Base::Console().Error("Could no open the response file\n"); - std::stringstream str; - str << "Could no open the response file: '" - << vm["response-file"].as() << "'" << endl; - throw Base::UnknownProgramOption(str.str()); - } - // Read the whole file into a string - stringstream ss; - ss << ifs.rdbuf(); - // Split the file content - char_separator sep(" \n\r"); - tokenizer > tok(ss.str(), sep); - vector args; - copy(tok.begin(), tok.end(), back_inserter(args)); - // Parse the file and store the options - store( boost::program_options::command_line_parser(args). - options(cmdline_options).positional(p).extra_parser(customSyntax).run(), vm); - } - - if (vm.count("version")) { - std::stringstream str; - str << mConfig["ExeName"] << " " << mConfig["ExeVersion"] - << " Revision: " << mConfig["BuildRevision"] << std::endl; - throw Base::ProgramInformation(str.str()); - } - - if (vm.count("console")) { - mConfig["RunMode"] = "Cmd"; - } - - if (vm.count("module-path")) { - vector Mods = vm["module-path"].as< vector >(); - string temp; - for (vector::const_iterator It= Mods.begin();It != Mods.end();++It) - temp += *It + ";"; - temp.erase(temp.end()-1); - mConfig["AdditionalModulePaths"] = temp; - } - - if (vm.count("python-path")) { - vector Paths = vm["python-path"].as< vector >(); - for (vector::const_iterator It= Paths.begin();It != Paths.end();++It) - Base::Interpreter().addPythonPath(It->c_str()); - } - - if (vm.count("input-file")) { - vector files(vm["input-file"].as< vector >()); - int OpenFileCount=0; - for (vector::const_iterator It = files.begin();It != files.end();++It) { - - //cout << "Input files are: " - // << vm["input-file"].as< vector >() << "\n"; - - std::ostringstream temp; - temp << "OpenFile" << OpenFileCount; - mConfig[temp.str()] = *It; - OpenFileCount++; - } - std::ostringstream buffer; - buffer << OpenFileCount; - mConfig["OpenFileCount"] = buffer.str(); - } - - if (vm.count("output")) { - string file = vm["output"].as(); - mConfig["SaveFile"] = file; - } - - if (vm.count("hidden")) { - mConfig["StartHidden"] = "1"; - } - - if (vm.count("write-log")) { - mConfig["LoggingFile"] = "1"; - //mConfig["LoggingFileName"] = vm["write-log"].as(); - mConfig["LoggingFileName"] = mConfig["UserAppData"] + mConfig["ExeName"] + ".log"; - } - - if (vm.count("log-file")) { - mConfig["LoggingFile"] = "1"; - mConfig["LoggingFileName"] = vm["log-file"].as(); - } - - if (vm.count("user-cfg")) { - mConfig["UserParameter"] = vm["user-cfg"].as(); - } - - if (vm.count("system-cfg")) { - mConfig["SystemParameter"] = vm["system-cfg"].as(); - } - - if (vm.count("run-test")) { - int level = vm["run-test"].as(); - switch (level) { - case '0': - // test script level 0 - mConfig["RunMode"] = "Internal"; - mConfig["ScriptFileName"] = "FreeCADTest"; - //sScriptName = FreeCADTest; - break; - default: - //default testing level 0 - mConfig["RunMode"] = "Internal"; - mConfig["ScriptFileName"] = "FreeCADTest"; - //sScriptName = FreeCADTest; - break; - }; - } - - if (vm.count("single-instance")) { - mConfig["SingleInstance"] = "1"; - } - - if (vm.count("dump-config")) { - std::stringstream str; - for (std::map::iterator it=mConfig.begin(); it != mConfig.end(); ++it) { - str << it->first << "=" << it->second << std::endl; - } - throw Base::ProgramInformation(str.str()); - } - - if (vm.count("get-config")) { - std::string configKey = vm["get-config"].as(); - std::stringstream str; - std::map::iterator pos; - pos = mConfig.find(configKey); - if (pos != mConfig.end()) { - str << pos->second; - } - str << std::endl; - throw Base::ProgramInformation(str.str()); - } -} - -void Application::ExtractUserPath() -{ - // std paths - mConfig["BinPath"] = mConfig["AppHomePath"] + "bin" + PATHSEP; - mConfig["DocPath"] = mConfig["AppHomePath"] + "doc" + PATHSEP; - -#if defined(FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_BSD) - // Default paths for the user specific stuff - struct passwd *pwd = getpwuid(getuid()); - if (pwd == NULL) - throw Base::Exception("Getting HOME path from system failed!"); - mConfig["UserHomePath"] = pwd->pw_dir; - std::string appData = pwd->pw_dir; - Base::FileInfo fi(appData.c_str()); - if (!fi.exists()) { - // This should never ever happen - std::stringstream str; - str << "Application data directory " << appData << " does not exist!"; - throw Base::Exception(str.str()); - } - - // In order to write into our data path, we must create some directories, first. - // If 'AppDataSkipVendor' is defined, the value of 'ExeVendor' must not be part of - // the path. - appData += PATHSEP; - appData += "."; - if (mConfig.find("AppDataSkipVendor") == mConfig.end()) { - appData += mConfig["ExeVendor"]; - fi.setFile(appData.c_str()); - if (!fi.exists() && !Py_IsInitialized()) { - if (!fi.createDirectory()) { - std::string error = "Cannot create directory "; - error += appData; - // Want more details on console - std::cerr << error << std::endl; - throw Base::Exception(error); - } - } - appData += PATHSEP; - } - - appData += mConfig["ExeName"]; - fi.setFile(appData.c_str()); - if (!fi.exists() && !Py_IsInitialized()) { - if (!fi.createDirectory()) { - std::string error = "Cannot create directory "; - error += appData; - // Want more details on console - std::cerr << error << std::endl; - throw Base::Exception(error); - } - } - - // Actually the name of the directory where the parameters are stored should be the name of - // the application due to branding reasons. - appData += PATHSEP; - mConfig["UserAppData"] = appData; - -#elif defined(FC_OS_MACOSX) - // Default paths for the user specific stuff on the platform - struct passwd *pwd = getpwuid(getuid()); - if (pwd == NULL) - throw Base::Exception("Getting HOME path from system failed!"); - mConfig["UserHomePath"] = pwd->pw_dir; - std::string appData = pwd->pw_dir; - appData += PATHSEP; - appData += "Library"; - appData += PATHSEP; - appData += "Preferences"; - Base::FileInfo fi(appData.c_str()); - if (!fi.exists()) { - // This should never ever happen - std::stringstream str; - str << "Application data directory " << appData << " does not exist!"; - throw Base::Exception(str.str()); - } - - // In order to write to our data path, we must create some directories, first. - // If 'AppDataSkipVendor' is defined the value of 'ExeVendor' must not be part of - // the path. - appData += PATHSEP; - if (mConfig.find("AppDataSkipVendor") == mConfig.end()) { - appData += mConfig["ExeVendor"]; - fi.setFile(appData.c_str()); - if (!fi.exists() && !Py_IsInitialized()) { - if (!fi.createDirectory()) { - std::string error = "Cannot create directory "; - error += appData; - // Want more details on console - std::cerr << error << std::endl; - throw Base::Exception(error); - } - } - appData += PATHSEP; - } - - appData += mConfig["ExeName"]; - fi.setFile(appData.c_str()); - if (!fi.exists() && !Py_IsInitialized()) { - if (!fi.createDirectory()) { - std::string error = "Cannot create directory "; - error += appData; - // Want more details on console - std::cerr << error << std::endl; - throw Base::Exception(error); - } - } - - // Actually the name of the directory where the parameters are stored should be the name of - // the application due to branding reasons. - appData += PATHSEP; - mConfig["UserAppData"] = appData; - -#elif defined(FC_OS_WIN32) - WCHAR szPath[MAX_PATH]; - TCHAR dest[MAX_PATH*3]; - // Get the default path where we can save our documents. It seems that - // 'CSIDL_MYDOCUMENTS' doesn't work on all machines, so we use 'CSIDL_PERSONAL' - // which does the same. - if (SUCCEEDED(SHGetFolderPathW(NULL, CSIDL_PERSONAL, NULL, 0, szPath))) { - WideCharToMultiByte(CP_UTF8, 0, szPath, -1,dest, 256, NULL, NULL); - mConfig["UserHomePath"] = dest; - } - else - mConfig["UserHomePath"] = mConfig["AppHomePath"]; - - // In the second step we want the directory where user settings of the application can be - // kept. There we create a directory with name of the vendor and a sub-directory with name - // of the application. - if (SUCCEEDED(SHGetFolderPathW(NULL, CSIDL_APPDATA, NULL, 0, szPath))) { - // convert to UTF8 - WideCharToMultiByte(CP_UTF8, 0, szPath, -1,dest, 256, NULL, NULL); - - std::string appData = dest; - Base::FileInfo fi(appData.c_str()); - if (!fi.exists()) { - // This should never ever happen - std::stringstream str; - str << "Application data directory " << appData << " does not exist!"; - throw Base::Exception(str.str()); - } - - // In order to write to our data path we must create some directories first. - // If 'AppDataSkipVendor' is defined the value of 'ExeVendor' must not be part of - // the path. - if (mConfig.find("AppDataSkipVendor") == mConfig.end()) { - appData += PATHSEP; - appData += mConfig["ExeVendor"]; - fi.setFile(appData.c_str()); - if (!fi.exists() && !Py_IsInitialized()) { - if (!fi.createDirectory()) { - std::string error = "Cannot create directory "; - error += appData; - // Want more details on console - std::cerr << error << std::endl; - throw Base::Exception(error); - } - } - } - - appData += PATHSEP; - appData += mConfig["ExeName"]; - fi.setFile(appData.c_str()); - if (!fi.exists() && !Py_IsInitialized()) { - if (!fi.createDirectory()) { - std::string error = "Cannot create directory "; - error += appData; - // Want more details on console - std::cerr << error << std::endl; - throw Base::Exception(error); - } - } - - // Actually the name of the directory where the parameters are stored should be the name of - // the application due to branding reasons. - appData += PATHSEP; - mConfig["UserAppData"] = appData; - } -#else -# error "Implement ExtractUserPath() for your platform." -#endif -} - -#if defined (FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_BSD) -#include -#include -#include - -std::string Application::FindHomePath(const char* sCall) -{ - // We have three ways to start this application either use one of the two executables or - // import the FreeCAD.so module from a running Python session. In the latter case the - // Python interpreter is already initialized. - std::string absPath; - std::string homePath; - if (Py_IsInitialized()) { - // Note: realpath is known to cause a buffer overflow because it - // expands the given path to an absolute path of unknown length. - // Even setting PATH_MAX does not necessarily solve the problem - // for sure but the risk of overflow is rather small. - char resolved[PATH_MAX]; - char* path = realpath(sCall, resolved); - if (path) - absPath = path; - } - else { - // Find the path of the executable. Theoretically, there could occur a - // race condition when using readlink, but we only use this method to - // get the absolute path of the executable to compute the actual home - // path. In the worst case we simply get q wrong path and FreeCAD is not - // able to load its modules. - char resolved[PATH_MAX]; - int nchars = readlink("/proc/self/exe", resolved, PATH_MAX); - if (nchars < 0 || nchars >= PATH_MAX) - throw Base::Exception("Cannot determine the absolute path of the executable"); - resolved[nchars] = '\0'; // enfore null termination - absPath = resolved; - } - - // should be an absolute path now - std::string::size_type pos = absPath.find_last_of("/"); - homePath.assign(absPath,0,pos); - pos = homePath.find_last_of("/"); - homePath.assign(homePath,0,pos+1); - - return homePath; -} - -#elif defined(FC_OS_MACOSX) -#include -#include -#include -#include - -std::string Application::FindHomePath(const char* call) -{ - uint32_t sz = 0; - char *buf; - - _NSGetExecutablePath(NULL, &sz); //function only returns "sz" if first arg is to small to hold value - buf = (char*) malloc(++sz); - - if (_NSGetExecutablePath(buf, &sz) == 0) { - char resolved[PATH_MAX]; - char* path = realpath(buf, resolved); - free(buf); - - if (path) { - std::string Call(resolved), TempHomePath; - std::string::size_type pos = Call.find_last_of(PATHSEP); - TempHomePath.assign(Call,0,pos); - pos = TempHomePath.find_last_of(PATHSEP); - TempHomePath.assign(TempHomePath,0,pos+1); - return TempHomePath; - } - } - - return call; // error -} - -#elif defined (FC_OS_WIN32) -std::string Application::FindHomePath(const char* sCall) -{ - // We have three ways to start this application either use one of the two executables or - // import the FreeCAD.pyd module from a running Python session. In the latter case the - // Python interpreter is already initialized. - wchar_t szFileName [MAX_PATH]; - if (Py_IsInitialized()) { - GetModuleFileNameW(GetModuleHandle(sCall),szFileName, MAX_PATH-1); - } - else { - GetModuleFileNameW(0, szFileName, MAX_PATH-1); - } - - std::wstring Call(szFileName), homePath; - std::wstring::size_type pos = Call.find_last_of(PATHSEP); - homePath.assign(Call,0,pos); - pos = homePath.find_last_of(PATHSEP); - homePath.assign(homePath,0,pos+1); - - // switch to posix style - for (std::wstring::iterator it = homePath.begin(); it != homePath.end(); ++it) { - if (*it == '\\') - *it = '/'; - } - - // fixes #0001638 to avoid to load DLLs from Windows' system directories before FreeCAD's bin folder - std::wstring binPath = homePath; - binPath += L"bin"; - SetDllDirectoryW(binPath.c_str()); - - // http://stackoverflow.com/questions/5625884/conversion-of-stdwstring-to-qstring-throws-linker-error -#ifdef _MSC_VER - QString str = QString::fromUtf16(reinterpret_cast(homePath.c_str())); -#else - QString str = QString::fromStdWString(homePath); -#endif - return str.toStdString(); -} - -#else -# error "std::string Application::FindHomePath(const char*) not implemented" -#endif diff --git a/src/App/CMakeLists.txt.orig b/src/App/CMakeLists.txt.orig deleted file mode 100644 index fa2232533..000000000 --- a/src/App/CMakeLists.txt.orig +++ /dev/null @@ -1,229 +0,0 @@ -if(WIN32) - add_definitions(-DFCApp) - add_definitions(-DBOOST_DYN_LINK) -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(DOCDIR) - add_definitions(-DDOCDIR="${DOCDIR}") -ENDIF(DOCDIR) - -include_directories( - ${CMAKE_BINARY_DIR}/src - ${CMAKE_SOURCE_DIR}/src - ${CMAKE_CURRENT_BINARY_DIR} - ${Boost_INCLUDE_DIRS} - ${PYTHON_INCLUDE_DIRS} - ${XercesC_INCLUDE_DIRS} - ${QT_INCLUDE_DIR} - ${ZLIB_INCLUDE_DIR} -) - -set(FreeCADApp_LIBS - FreeCADBase - ${Boost_LIBRARIES} - ${QT_QTCORE_LIBRARY} - ${QT_QTXML_LIBRARY} -) - -generate_from_xml(DocumentPy) -generate_from_xml(DocumentObjectPy) -generate_from_xml(DocumentObjectGroupPy) -generate_from_xml(GeoFeaturePy) -generate_from_xml(GeoFeatureGroupPy) -generate_from_xml(PartPy) - -generate_from_xml(ComplexGeoDataPy) -generate_from_xml(PropertyContainerPy) -generate_from_xml(MaterialPy) - -generate_from_py(FreeCADInit InitScript.h) -generate_from_py(FreeCADTest TestScript.h) - -SET(FreeCADApp_XML_SRCS - DocumentObjectGroupPy.xml - DocumentObjectPy.xml - GeoFeaturePy.xml - GeoFeatureGroupPy.xml - PartPy.xml - DocumentPy.xml - PropertyContainerPy.xml - ComplexGeoDataPy.xml - MaterialPy.xml -) -SOURCE_GROUP("XML" FILES ${FreeCADApp_XML_SRCS}) - -# The document stuff -SET(Document_CPP_SRCS - Annotation.cpp - Document.cpp - DocumentObject.cpp - DocumentObjectFileIncluded.cpp - DocumentObjectGroup.cpp - DocumentObjectGroupPyImp.cpp - PartPyImp.cpp - GeoFeaturePyImp.cpp - DocumentObjectPyImp.cpp - DocumentObserver.cpp - DocumentObserverPython.cpp - DocumentPyImp.cpp - Expression.cpp - FeaturePython.cpp - FeatureTest.cpp - GeoFeature.cpp - GeoFeatureGroupPyImp.cpp - GeoFeatureGroup.cpp - Part.cpp - Origin.cpp - Path.cpp - InventorObject.cpp - MeasureDistance.cpp - Placement.cpp -<<<<<<< ae7effa304095ee3d286ea7bb545636960e262d5 - Plane.cpp - Range.cpp - Line.cpp -======= - OriginFeature.cpp ->>>>>>> App/Origin: big refactoring - Transactions.cpp - VRMLObject.cpp - MaterialObject.cpp - MergeDocuments.cpp -) - -SET(Document_HPP_SRCS - Annotation.h - Document.h - DocumentObject.h - DocumentObjectFileIncluded.h - DocumentObjectGroup.h - DocumentObserver.h - DocumentObserverPython.h - Expression.h - ExpressionVisitors.h - FeatureCustom.h - FeaturePython.h - FeaturePythonPyImp.h - FeaturePythonPyImp.inl - FeatureTest.h - GeoFeature.h - GeoFeatureGroup.h - Part.h - Origin.h - Path.h - InventorObject.h - MeasureDistance.h - Placement.h -<<<<<<< ae7effa304095ee3d286ea7bb545636960e262d5 - Plane.h - Range.h - Line.h -======= - OriginFeature.h ->>>>>>> App/Origin: big refactoring - Transactions.h - VRMLObject.h - MaterialObject.h - MergeDocuments.h -) -SET(Document_SRCS - ${Document_CPP_SRCS} - ${Document_HPP_SRCS} -) -SOURCE_GROUP("Document" FILES ${Document_SRCS}) - -# The property stuff -SET(Properties_CPP_SRCS - DynamicProperty.cpp - ObjectIdentifier.cpp - Property.cpp - PropertyContainer.cpp - PropertyContainerPyImp.cpp - PropertyFile.cpp - PropertyGeo.cpp - PropertyLinks.cpp - PropertyPythonObject.cpp - PropertyStandard.cpp - PropertyUnits.cpp - PropertyExpressionEngine.cpp -) -SET(Properties_HPP_SRCS - DynamicProperty.h - ObjectIdentifier.h - Property.h - PropertyContainer.h - PropertyFile.h - PropertyGeo.h - PropertyLinks.h - PropertyPythonObject.h - PropertyStandard.h - PropertyUnits.h - PropertyExpressionEngine.h -) -SET(Properties_SRCS - ${Properties_CPP_SRCS} - ${Properties_HPP_SRCS} -) -SOURCE_GROUP("Properties" FILES ${Properties_SRCS}) - -SET(FreeCADApp_CPP_SRCS - ${Document_CPP_SRCS} - ${Properties_CPP_SRCS} - Application.cpp - ApplicationPy.cpp - Branding.cpp - ColorModel.cpp - ComplexGeoData.cpp - ComplexGeoDataPyImp.cpp - Enumeration.cpp - Material.cpp - MaterialPyImp.cpp -) - -SET(FreeCADApp_HPP_SRCS - ${Document_HPP_SRCS} - ${Properties_HPP_SRCS} - Application.h - Branding.h - ColorModel.h - ComplexGeoData.h - Enumeration.h - Material.h -) - -SET(FreeCADApp_SRCS - ${FreeCADApp_CPP_SRCS} - ${FreeCADApp_HPP_SRCS} - ${FreeCADApp_XML_SRCS} - FreeCADInit.py - FreeCADTest.py - PreCompiled.cpp - PreCompiled.h -) - -if(MSVC) - add_definitions(-D_PreComp_) - ADD_MSVC_PRECOMPILED_HEADER(FreeCADApp PreCompiled.h PreCompiled.cpp FreeCADApp_CPP_SRCS) -endif(MSVC) - -add_library(FreeCADApp SHARED ${FreeCADApp_SRCS}) - -target_link_libraries(FreeCADApp ${FreeCADApp_LIBS}) - -SET_BIN_DIR(FreeCADApp FreeCADApp) - -if(WIN32) - INSTALL(TARGETS FreeCADApp - RUNTIME DESTINATION bin - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} - ) -else(WIN32) - INSTALL(TARGETS FreeCADApp - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} - ) -endif(WIN32) diff --git a/src/App/Document.h.orig b/src/App/Document.h.orig deleted file mode 100644 index 24f469593..000000000 --- a/src/App/Document.h.orig +++ /dev/null @@ -1,375 +0,0 @@ -/*************************************************************************** - * Copyright (c) Jürgen Riegel (juergen.riegel@web.de) 2002 * - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file COPYING.LIB. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * - ***************************************************************************/ - -#ifndef APP_DOCUMENT_H -#define APP_DOCUMENT_H - -#include -#include -#include -#include - -#include "PropertyContainer.h" -#include "PropertyStandard.h" -#include "PropertyLinks.h" - -#include -#include -#include - -#include -#include - - -namespace Base { - class Writer; -} - -namespace App -{ - class DocumentObject; - class DocumentObjectExecReturn; - class Document; - class DocumentPy; // the python document class - class Application; - class Transaction; -} - -namespace App -{ - -/// The document class -class AppExport Document : public App::PropertyContainer -{ - PROPERTY_HEADER(App::Document); - -public: - /** @name Properties */ - //@{ - /// holds the long name of the document (utf-8 coded) - PropertyString Label; - /// full qualified (with path) file name (utf-8 coded) - PropertyString FileName; - /// creators name (utf-8) - PropertyString CreatedBy; - PropertyString CreationDate; - /// user last modified the document - PropertyString LastModifiedBy; - PropertyString LastModifiedDate; - /// company name UTF8(optional) - PropertyString Company; - /// long comment or description (UTF8 with line breaks) - PropertyString Comment; - /// Id e.g. Part number - PropertyString Id; - /// unique identifier of the document - PropertyUUID Uid; - /** License string - * Holds the short license string for the Item, e.g. CC-BY - * for the Creative Commons license suit. - */ - App::PropertyString License; - /// License descripton/contract URL - App::PropertyString LicenseURL; - /// Meta descriptons - App::PropertyMap Meta; - /// Material descriptons, used and defined in the Material module. - App::PropertyMap Material; - /// read-only name of the temp dir created wen the document is opened - PropertyString TransientDir; - /// Tip object of the document (if any) - PropertyLink Tip; - /// Tip object of the document (if any) - PropertyString TipName; - //@} - - /** @name Signals of the document */ - //@{ - /// signal on new Object - boost::signal signalNewObject; - //boost::signal m_sig; - /// signal on deleted Object - boost::signal signalDeletedObject; - /// signal on changed Object - boost::signal signalChangedObject; - /// signal on relabeled Object - boost::signal signalRelabelObject; - /// signal on activated Object - boost::signal signalActivatedObject; - /// signal on undo - boost::signal signalUndo; - /// signal on redo - boost::signal signalRedo; - /** signal on load/save document - * this signal is given when the document gets streamed. - * you can use this hook to write additional information in - * the file (like the Gui::Document it does). - */ - boost::signal signalSaveDocument; - boost::signal signalRestoreDocument; - boost::signal&, - Base::Writer &)> signalExportObjects; - boost::signal&, - Base::Writer &)> signalExportViewObjects; - boost::signal&, - Base::XMLReader&)> signalImportObjects; - boost::signal&, Base::Reader&, - const std::map&)> signalImportViewObjects; - boost::signal signalRecomputed; - //@} - - /** @name File handling of the document */ - //@{ - /// Save the Document under a new Name - //void saveAs (const char* Name); - /// Save the document to the file in Property Path - bool save (void); - bool saveAs(const char* file); - bool saveCopy(const char* file); - /// Restore the document from the file in Property Path - void restore (void); - void exportObjects(const std::vector&, std::ostream&); - void exportGraphviz(std::ostream&) const; - std::vector importObjects(Base::XMLReader& reader); - /// Opens the document from its file name - //void open (void); - /// Is the document already saved to a file - bool isSaved() const; - /// Get the document name - const char* getName() const; - //@} - - virtual void Save (Base::Writer &writer) const; - virtual void Restore(Base::XMLReader &reader); - - /// returns the complet document mermory consumption, including all managed DocObjects and Undo Redo. - unsigned int getMemSize (void) const; - - /** @name Object handling */ - //@{ - /** Add a feature of sType with sName (ASCII) to this document and set it active. -<<<<<<< aed54b532a8900cea389cf5b8a9e941402f9728f - * Unicode names are set through the Label property. - */ - DocumentObject *addObject(const char* sType, const char* pObjectName=0); -======= - * Unicode names are set through the Label propery. - * @param sType the type of created object - * @param pObjectName if nonNULL use that name otherwise generate a new uniq name based on the \a sType - * @param isNew if false don't call the \c DocumentObject::setupObject() callback (default is true) - */ - DocumentObject *addObject(const char* sType, const char* pObjectName=0, bool isNew=true); ->>>>>>> App: add two callback to DocumentObject to perform initialization/uninitialization inside an object - /// Remove a feature out of the document - void remObject(const char* sName); - /** Add an existing feature with sName (ASCII) to this document and set it active. - * Unicode names are set through the Label property. - * This is an overloaded function of the function above and can be used to create - * a feature outside and add it to the document afterwards. - * \note The passed feature must not yet be added to a document, otherwise an exception - * is raisedd. - */ - void addObject(DocumentObject*, const char* pObjectName=0); - - - /** Copy an object from another document to this document - * If \a recursive is true then all objects this object depends on - * are copied as well. By default \a recursive is false. - * Returns the copy of the object or 0 if the creation failed. - */ - DocumentObject* copyObject(DocumentObject* obj, bool recursive=false); - /** Move an object from another document to this document - * If \a recursive is true then all objects this object depends on - * are moved as well. By default \a recursive is false. - * Returns the moved object itself or 0 if the object is already part of this - * document.. - */ - DocumentObject* moveObject(DocumentObject* obj, bool recursive=false); - /// Returns the active Object of this document - DocumentObject *getActiveObject(void) const; - /// Returns a Object of this document - DocumentObject *getObject(const char *Name) const; - /// Returns true if the DocumentObject is contained in this document - const bool isIn(const DocumentObject *pFeat) const; - /// Returns a Name of an Object or 0 - const char *getObjectName(DocumentObject *pFeat) const; - /// Returns a Name of an Object or 0 - std::string getUniqueObjectName(const char *Name) const; - /// Returns a name of the form prefix_number. d specifies the number of digits. - std::string getStandardObjectName(const char *Name, int d) const; - /// Returns a list of all Objects - std::vector getObjects() const; - std::vector getObjectsOfType(const Base::Type& typeId) const; - std::vector findObjects(const Base::Type& typeId, const char* objname) const; - /// Returns an array with the correct types already. - template inline std::vector getObjectsOfType() const; - int countObjectsOfType(const Base::Type& typeId) const; - /// get the number of objects in the document - int countObjects(void) const; - //@} - - /** @name methods for modification and state handling - */ - //@{ - /// Remove all modifications. After this call The document becomes again Valid. - void purgeTouched(); - /// check if there is any touched object in this document - bool isTouched(void) const; - /// returns all touched objects - std::vector getTouched(void) const; - /// set the document to be closable, this is on by default. - void setClosable(bool); - /// check whether the document can be closed - bool isClosable() const; - /// Recompute all touched features - void recompute(); - /// Recompute only one feature - void recomputeFeature(DocumentObject* Feat); - /// get the error log from the recompute run - const std::vector &getRecomputeLog(void)const{return _RecomputeLog;} - /// get the text of the error of a spezified object - const char* getErrorDescription(const App::DocumentObject*) const; - //@} - - - /** @name methods for the UNDO REDO and Transaction handling */ - //@{ - /// switch the level of Undo/Redo - void setUndoMode(int iMode); - /// switch the level of Undo/Redo - int getUndoMode(void) const; - /// switch the tranaction mode - void setTransactionMode(int iMode); - /// Open a new command Undo/Redo, an UTF-8 name can be specified - void openTransaction(const char* name=0); - // Commit the Command transaction. Do nothing If there is no Command transaction open. - void commitTransaction(); - /// Abort the actually running transaction. - void abortTransaction(); - /// Check if a transaction is open - bool hasPendingTransaction() const; - /// Set the Undo limit in Byte! - void setUndoLimit(unsigned int UndoMemSize=0); - /// Returns the actual memory consumption of the Undo redo stuff. - unsigned int getUndoMemSize (void) const; - /// Set the Undo limit as stack size - void setMaxUndoStackSize(unsigned int UndoMaxStackSize=20); - /// Set the Undo limit as stack size - unsigned int getMaxUndoStackSize(void)const; - /// Remove all stored Undos and Redos - void clearUndos(); - /// Returns the number of stored Undos. If greater than 0 Undo will be effective. - int getAvailableUndos() const; - /// Returns a list of the Undo names - std::vector getAvailableUndoNames() const; - /// Will UNDO one step, returns False if no undo was done (Undos == 0). - bool undo(); - /// Returns the number of stored Redos. If greater than 0 Redo will be effective. - int getAvailableRedos() const; - /// Returns a list of the Redo names. - std::vector getAvailableRedoNames() const; - /// Will REDO one step, returns False if no redo was done (Redos == 0). - bool redo() ; - //@} - - /** @name dependency stuff */ - //@{ - /// write GraphViz file - void writeDependencyGraphViz(std::ostream &out); - /// checks if the graph is directed and has no cycles - bool checkOnCycle(void); - /// get a list of all objects linking to the given object - std::vector getInList(const DocumentObject* me) const; - /// Get a complete list of all objects the given objects depend on. The list - /// also contains the given objects! - std::vector getDependencyList - (const std::vector&) const; - // set Changed - //void setChanged(DocumentObject* change); - //@} - - /// Function called to signal that an object identifier has been renamed - void renameObjectIdentifiers(const std::map & paths); - - virtual PyObject *getPyObject(void); - - friend class Application; - /// because of transaction handling - friend class DocumentObject; - friend class Transaction; - friend class TransactionObject; - - /// Destruction - virtual ~Document(); - -protected: - /// Construction - Document(void); - - void _remObject(DocumentObject* pcObject); - void _addObject(DocumentObject* pcObject, const char* pObjectName); - /// checks if a valid transaction is open - void _checkTransaction(DocumentObject* pcObject); - void breakDependency(DocumentObject* pcObject, bool clear); - std::vector readObjects(Base::XMLReader& reader); - void writeObjects(const std::vector&, Base::Writer &writer) const; - - void onChanged(const Property* prop); - /// callback from the Document objects before property will be changed - void onBeforeChangeProperty(const DocumentObject *Who, const Property *What); - /// callback from the Document objects after property was changed - void onChangedProperty(const DocumentObject *Who, const Property *What); - /// helper which Recompute only this feature - bool _recomputeFeature(DocumentObject* Feat); - void _clearRedos(); - /// refresh the internal dependency graph - void _rebuildDependencyList(void); - std::string getTransientDirectoryName(const std::string& uuid, const std::string& filename) const; - - -private: - // # Data Member of the document +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - std::list mUndoTransactions; - std::list mRedoTransactions; - // recompute log - std::vector _RecomputeLog; - - // pointer to the python class - Py::Object DocumentPythonObject; - struct DocumentP* d; -}; - -template -inline std::vector Document::getObjectsOfType() const -{ - std::vector type; - std::vector obj = this->getObjectsOfType(T::getClassTypeId()); - type.reserve(obj.size()); - for (std::vector::iterator it = obj.begin(); it != obj.end(); ++it) - type.push_back(static_cast(*it)); - return type; -} - - -} //namespace App - -#endif // APP_DOCUMENT_H diff --git a/src/Gui/Selection.cpp.orig b/src/Gui/Selection.cpp.orig deleted file mode 100644 index 019c82725..000000000 --- a/src/Gui/Selection.cpp.orig +++ /dev/null @@ -1,1313 +0,0 @@ -/*************************************************************************** - * Copyright (c) Juergen Riegel * - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file COPYING.LIB. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * - ***************************************************************************/ - - -#include "PreCompiled.h" - -#ifndef _PreComp_ -# include -# include -# include -# include -# include -# include -# include -#endif - -/// Here the FreeCAD includes sorted by Base,App,Gui...... -#include "Application.h" -#include "Document.h" -#include "Selection.h" -#include "SelectionFilter.h" -#include "SelectionObjectPy.h" -#include "View3DInventor.h" -#include -#include -#include -#include -#include -#include -#include -#include "MainWindow.h" - - - -using namespace Gui; -using namespace std; - -SelectionObserver::SelectionObserver() -{ - attachSelection(); -} - -SelectionObserver::~SelectionObserver() -{ - detachSelection(); -} - -bool SelectionObserver::blockConnection(bool block) -{ - bool ok = connectSelection.blocked(); - if (block) - connectSelection.block(); - else - connectSelection.unblock(); - return ok; -} - -bool SelectionObserver::isConnectionBlocked() const -{ - return connectSelection.blocked(); -} - -void SelectionObserver::attachSelection() -{ - if (!connectSelection.connected()) { - connectSelection = Selection().signalSelectionChanged.connect(boost::bind - (&SelectionObserver::onSelectionChanged, this, _1)); - } -} - -void SelectionObserver::detachSelection() -{ - if (connectSelection.connected()) { - connectSelection.disconnect(); - } -} - -// ------------------------------------------- - -std::vector SelectionObserverPython::_instances; - -SelectionObserverPython::SelectionObserverPython(const Py::Object& obj) : inst(obj) -{ -} - -SelectionObserverPython::~SelectionObserverPython() -{ -} - -void SelectionObserverPython::addObserver(const Py::Object& obj) -{ - _instances.push_back(new SelectionObserverPython(obj)); -} - -void SelectionObserverPython::removeObserver(const Py::Object& obj) -{ - SelectionObserverPython* obs=0; - for (std::vector::iterator it = - _instances.begin(); it != _instances.end(); ++it) { - if ((*it)->inst == obj) { - obs = *it; - _instances.erase(it); - break; - } - } - - delete obs; -} - -void SelectionObserverPython::onSelectionChanged(const SelectionChanges& msg) -{ - switch (msg.Type) - { - case SelectionChanges::AddSelection: - addSelection(msg); - break; - case SelectionChanges::RmvSelection: - removeSelection(msg); - break; - case SelectionChanges::SetSelection: - setSelection(msg); - break; - case SelectionChanges::ClrSelection: - clearSelection(msg); - break; - case SelectionChanges::SetPreselect: - setPreselection(msg); - break; - case SelectionChanges::RmvPreselect: - removePreselection(msg); - break; - default: - break; - } -} - -void SelectionObserverPython::addSelection(const SelectionChanges& msg) -{ - Base::PyGILStateLocker lock; - try { - if (this->inst.hasAttr(std::string("addSelection"))) { - Py::Callable method(this->inst.getAttr(std::string("addSelection"))); - Py::Tuple args(4); - args.setItem(0, Py::String(msg.pDocName ? msg.pDocName : "")); - args.setItem(1, Py::String(msg.pObjectName ? msg.pObjectName : "")); - args.setItem(2, Py::String(msg.pSubName ? msg.pSubName : "")); - Py::Tuple tuple(3); - tuple[0] = Py::Float(msg.x); - tuple[1] = Py::Float(msg.y); - tuple[2] = Py::Float(msg.z); - args.setItem(3, tuple); - method.apply(args); - } - } - catch (Py::Exception&) { - Base::PyException e; // extract the Python error text - e.ReportException(); - } -} - -void SelectionObserverPython::removeSelection(const SelectionChanges& msg) -{ - Base::PyGILStateLocker lock; - try { - if (this->inst.hasAttr(std::string("removeSelection"))) { - Py::Callable method(this->inst.getAttr(std::string("removeSelection"))); - Py::Tuple args(3); - args.setItem(0, Py::String(msg.pDocName ? msg.pDocName : "")); - args.setItem(1, Py::String(msg.pObjectName ? msg.pObjectName : "")); - args.setItem(2, Py::String(msg.pSubName ? msg.pSubName : "")); - method.apply(args); - } - } - catch (Py::Exception&) { - Base::PyException e; // extract the Python error text - e.ReportException(); - } -} - -void SelectionObserverPython::setSelection(const SelectionChanges& msg) -{ - Base::PyGILStateLocker lock; - try { - if (this->inst.hasAttr(std::string("setSelection"))) { - Py::Callable method(this->inst.getAttr(std::string("setSelection"))); - Py::Tuple args(1); - args.setItem(0, Py::String(msg.pDocName ? msg.pDocName : "")); - method.apply(args); - } - } - catch (Py::Exception&) { - Base::PyException e; // extract the Python error text - e.ReportException(); - } -} - -void SelectionObserverPython::clearSelection(const SelectionChanges& msg) -{ - Base::PyGILStateLocker lock; - try { - if (this->inst.hasAttr(std::string("clearSelection"))) { - Py::Callable method(this->inst.getAttr(std::string("clearSelection"))); - Py::Tuple args(1); - args.setItem(0, Py::String(msg.pDocName ? msg.pDocName : "")); - method.apply(args); - } - } - catch (Py::Exception&) { - Base::PyException e; // extract the Python error text - e.ReportException(); - } -} - -void SelectionObserverPython::setPreselection(const SelectionChanges& msg) -{ - Base::PyGILStateLocker lock; - try { - if (this->inst.hasAttr(std::string("setPreselection"))) { - Py::Callable method(this->inst.getAttr(std::string("setPreselection"))); - Py::Tuple args(3); - args.setItem(0, Py::String(msg.pDocName ? msg.pDocName : "")); - args.setItem(1, Py::String(msg.pObjectName ? msg.pObjectName : "")); - args.setItem(2, Py::String(msg.pSubName ? msg.pSubName : "")); - method.apply(args); - } - } - catch (Py::Exception&) { - Base::PyException e; // extract the Python error text - e.ReportException(); - } -} - -void SelectionObserverPython::removePreselection(const SelectionChanges& msg) -{ - Base::PyGILStateLocker lock; - try { - if (this->inst.hasAttr(std::string("removePreselection"))) { - Py::Callable method(this->inst.getAttr(std::string("removePreselection"))); - Py::Tuple args(3); - args.setItem(0, Py::String(msg.pDocName ? msg.pDocName : "")); - args.setItem(1, Py::String(msg.pObjectName ? msg.pObjectName : "")); - args.setItem(2, Py::String(msg.pSubName ? msg.pSubName : "")); - method.apply(args); - } - } - catch (Py::Exception&) { - Base::PyException e; // extract the Python error text - e.ReportException(); - } -} - -// ------------------------------------------- - -bool SelectionSingleton::hasSelection() const -{ - return !_SelList.empty(); -} - -std::vector SelectionSingleton::getCompleteSelection() const -{ - std::vector temp; - SelObj tempSelObj; - - for(std::list<_SelObj>::const_iterator It = _SelList.begin();It != _SelList.end();++It) { - tempSelObj.DocName = It->DocName.c_str(); - tempSelObj.FeatName = It->FeatName.c_str(); - tempSelObj.SubName = It->SubName.c_str(); - tempSelObj.TypeName = It->TypeName.c_str(); - tempSelObj.pObject = It->pObject; - tempSelObj.pDoc = It->pDoc; - temp.push_back(tempSelObj); - } - - return temp; -} - -std::vector SelectionSingleton::getSelection(const char* pDocName) const -{ - std::vector temp; - SelObj tempSelObj; - - App::Document *pcDoc; - pcDoc = getDocument(pDocName); - - if (!pcDoc) - return temp; - - for(std::list<_SelObj>::const_iterator It = _SelList.begin();It != _SelList.end();++It) { - if (It->pDoc == pcDoc) { - tempSelObj.DocName = It->DocName.c_str(); - tempSelObj.FeatName = It->FeatName.c_str(); - tempSelObj.SubName = It->SubName.c_str(); - tempSelObj.TypeName = It->TypeName.c_str(); - tempSelObj.pObject = It->pObject; - tempSelObj.pDoc = It->pDoc; - tempSelObj.x = It->x; - tempSelObj.y = It->y; - tempSelObj.z = It->z; - temp.push_back(tempSelObj); - } - } - - return temp; -} - -bool SelectionSingleton::hasSelection(const char* doc) const -{ - App::Document *pcDoc; - pcDoc = getDocument(doc); - if (!pcDoc) - return false; - for(std::list<_SelObj>::const_iterator It = _SelList.begin();It != _SelList.end();++It) { - if (It->pDoc == pcDoc) { - return true; - } - } - - return false; -} - -std::vector SelectionSingleton::getSelectionEx(const char* pDocName, Base::Type typeId) const -{ - std::vector temp; - std::map SortMap; - - // check the type - if (typeId == Base::Type::badType()) - return temp; - - App::Document *pcDoc; - string DocName; - - pcDoc = getDocument(pDocName); - - if (!pcDoc) - return temp; - - for (std::list<_SelObj>::const_iterator It = _SelList.begin();It != _SelList.end();++It) { - if (It->pDoc == pcDoc) { - // right type? - if (It->pObject->getTypeId().isDerivedFrom(typeId)){ - // if the object has already an entry - if (SortMap.find(It->pObject) != SortMap.end()){ - // only add sub-element - if (!It->SubName.empty()) { - SortMap[It->pObject].SubNames.push_back(It->SubName); - SortMap[It->pObject].SelPoses.push_back(Base::Vector3d(It->x,It->y,It->z)); - } - } - else { - // create a new entry - SelectionObject tempSelObj; - tempSelObj.DocName = It->DocName; - tempSelObj.FeatName = It->FeatName; - tempSelObj.TypeName = It->TypeName.c_str(); - if (!It->SubName.empty()) { - tempSelObj.SubNames.push_back(It->SubName); - tempSelObj.SelPoses.push_back(Base::Vector3d(It->x,It->y,It->z)); - } - SortMap.insert(std::pair(It->pObject,tempSelObj)); - } - } - } - } - - // The map looses the order thus we have to go again through the list and pick up the SelectionObject from the map - for (std::list<_SelObj>::const_iterator It = _SelList.begin();It != _SelList.end();++It) { - std::map::iterator Jt = SortMap.find(It->pObject); - if (Jt != SortMap.end()) { - temp.push_back(Jt->second); - SortMap.erase(Jt); - } - } - - return temp; -} - -int SelectionSingleton::getAsPropertyLinkSubList(App::PropertyLinkSubList &prop) const -{ - std::vector sel = this->getSelectionEx(); - std::vector objs; objs.reserve(sel.size()*2); - std::vector subs; subs.reserve(sel.size()*2); - for( int iobj = 0 ; iobj < sel.size() ; iobj++ ){ - Gui::SelectionObject &selitem = sel[iobj]; - App::DocumentObject* obj = selitem.getObject(); - const std::vector &subnames = selitem.getSubNames(); - if (subnames.size() == 0){//whole object is selected - objs.push_back(obj); - subs.push_back(std::string()); - } else { - for( int isub = 0 ; isub < subnames.size() ; isub++ ){ - objs.push_back(obj); - subs.push_back(subnames[isub]); - } - } - } - assert(objs.size()==subs.size()); - prop.setValues(objs, subs); - return objs.size(); -} - -vector SelectionSingleton::getObjectsOfType(const Base::Type& typeId, const char* pDocName) const -{ - std::vector temp; - App::Document *pcDoc; - - pcDoc = getDocument(pDocName); - - if (!pcDoc) - return temp; - - for (std::list<_SelObj>::const_iterator It = _SelList.begin();It != _SelList.end();++It) { - if (It->pDoc == pcDoc && It->pObject && It->pObject->getTypeId().isDerivedFrom(typeId)) { - temp.push_back(It->pObject); - } - } - - return temp; -} - -std::vector SelectionSingleton::getObjectsOfType(const char* typeName, const char* pDocName) const -{ - Base::Type typeId = Base::Type::fromName(typeName); - if (typeId == Base::Type::badType()) - return std::vector(); - return getObjectsOfType(typeId, pDocName); -} - -unsigned int SelectionSingleton::countObjectsOfType(const Base::Type& typeId, const char* pDocName) const -{ - unsigned int iNbr=0; - App::Document *pcDoc; - - pcDoc = getDocument(pDocName); - - if (!pcDoc) - return 0; - - for (std::list<_SelObj>::const_iterator It = _SelList.begin();It != _SelList.end();++It) { - if (It->pDoc == pcDoc && It->pObject && It->pObject->getTypeId().isDerivedFrom(typeId)) { - iNbr++; - } - } - - return iNbr; -} - -unsigned int SelectionSingleton::countObjectsOfType(const char* typeName, const char* pDocName) const -{ - Base::Type typeId = Base::Type::fromName(typeName); - if (typeId == Base::Type::badType()) - return 0; - return countObjectsOfType(typeId, pDocName); -} - -bool SelectionSingleton::setPreselect(const char* pDocName, const char* pObjectName, const char* pSubName, float x, float y, float z) -{ - static char buf[513]; - - if (DocName != "") - rmvPreselect(); - - if (ActiveGate) { - App::Document* pDoc = getDocument(pDocName); - if (pDoc) { - if (pObjectName) { - App::DocumentObject* pObject = pDoc->getObject(pObjectName); - if (!ActiveGate->allow(pDoc,pObject,pSubName)) { - QString msg; - if (ActiveGate->notAllowedReason.length() > 0){ - msg = QObject::tr(ActiveGate->notAllowedReason.c_str()); - } else { - msg = QCoreApplication::translate("SelectionFilter","Not allowed:"); - } - msg.append( - QObject::tr(" %1.%2.%3 ") - .arg(QString::fromAscii(pDocName)) - .arg(QString::fromAscii(pObjectName)) - .arg(QString::fromAscii(pSubName)) - ); - - if (getMainWindow()) { -<<<<<<< 18faa737da36035dd5ff84b1a5e26e38fd5194e1 - getMainWindow()->showMessage(QString::fromLatin1(buf),3000); -======= - getMainWindow()->showMessage(msg,3000); ->>>>>>> SelectionGate: add capability to display why not allowed. - Gui::MDIView* mdi = Gui::Application::Instance->activeDocument()->getActiveView(); - mdi->setOverrideCursor(QCursor(Qt::ForbiddenCursor)); - } - return false; - } - - } - else - return ActiveGate->allow(pDoc,0,0); - } - else - return false; - - } - - DocName = pDocName; - FeatName= pObjectName; - SubName = pSubName; - hx = x; - hy = y; - hz = z; - - // set up the change object - SelectionChanges Chng; - Chng.pDocName = DocName.c_str(); - Chng.pObjectName = FeatName.c_str(); - Chng.pSubName = SubName.c_str(); - Chng.x = x; - Chng.y = y; - Chng.z = z; - Chng.Type = SelectionChanges::SetPreselect; - - // set the current preselection - CurrentPreselection = Chng; - - snprintf(buf,512,"Preselected: %s.%s.%s (%f,%f,%f)",Chng.pDocName - ,Chng.pObjectName - ,Chng.pSubName - ,x,y,z); - - //FIXME: We shouldn't replace the possibly defined edit cursor - //with the arrow cursor. But it seems that we don't even have to. - //if (getMainWindow()){ - // getMainWindow()->showMessage(QString::fromLatin1(buf),3000); - // Gui::MDIView* mdi = Gui::Application::Instance->activeDocument()->getActiveView(); - // mdi->restoreOverrideCursor(); - //} - - Notify(Chng); - signalSelectionChanged(Chng); - - //Base::Console().Log("Sel : Add preselect %s \n",pObjectName); - - // allows the preselection - return true; -} - -void SelectionSingleton::setPreselectCoord( float x, float y, float z) -{ - static char buf[513]; - - // if nothing is in preselect ignore - if(!CurrentPreselection.pObjectName) return; - - CurrentPreselection.x = x; - CurrentPreselection.y = y; - CurrentPreselection.z = z; - - snprintf(buf,512,"Preselected: %s.%s.%s (%f,%f,%f)",CurrentPreselection.pDocName - ,CurrentPreselection.pObjectName - ,CurrentPreselection.pSubName - ,x,y,z); - - if (getMainWindow()) - getMainWindow()->showMessage(QString::fromLatin1(buf),3000); -} - -void SelectionSingleton::rmvPreselect() -{ - if (DocName == "") - return; - - SelectionChanges Chng; - Chng.pDocName = DocName.c_str(); - Chng.pObjectName = FeatName.c_str(); - Chng.pSubName = SubName.c_str(); - Chng.Type = SelectionChanges::RmvPreselect; - - // reset the current preselection - CurrentPreselection.pDocName =0; - CurrentPreselection.pObjectName = 0; - CurrentPreselection.pSubName = 0; - CurrentPreselection.x = 0.0; - CurrentPreselection.y = 0.0; - CurrentPreselection.z = 0.0; - - // notify observing objects - Notify(Chng); - signalSelectionChanged(Chng); - - DocName = ""; - FeatName= ""; - SubName = ""; - hx = 0; - hy = 0; - hz = 0; - - if (ActiveGate && getMainWindow()) { - Gui::MDIView* mdi = Gui::Application::Instance->activeDocument()->getActiveView(); - mdi->restoreOverrideCursor(); - } - - //Base::Console().Log("Sel : Rmv preselect \n"); -} - -const SelectionChanges &SelectionSingleton::getPreselection(void) const -{ - return CurrentPreselection; -} - -// add a SelectionGate to control what is selectable -void SelectionSingleton::addSelectionGate(Gui::SelectionGate *gate) -{ - if (ActiveGate) - rmvSelectionGate(); - - ActiveGate = gate; - -} - -// remove the active SelectionGate -void SelectionSingleton::rmvSelectionGate(void) -{ - if (ActiveGate) { - delete ActiveGate; - ActiveGate=0; - Gui::Document* doc = Gui::Application::Instance->activeDocument(); - if (doc) { - Gui::MDIView* mdi = doc->getActiveView(); - mdi->restoreOverrideCursor(); - } - } -} - - -App::Document* SelectionSingleton::getDocument(const char* pDocName) const -{ - if (pDocName) - return App::GetApplication().getDocument(pDocName); - else - return App::GetApplication().getActiveDocument(); -} - -bool SelectionSingleton::addSelection(const char* pDocName, const char* pObjectName, const char* pSubName, float x, float y, float z) -{ - // already in ? - if (isSelected(pDocName, pObjectName, pSubName)) - return true; - - _SelObj temp; - - temp.pDoc = getDocument(pDocName); - - if (temp.pDoc) { - if(pObjectName) - temp.pObject = temp.pDoc->getObject(pObjectName); - else - temp.pObject = 0; - - // check for a Selection Gate - if (ActiveGate) { - if (!ActiveGate->allow(temp.pDoc,temp.pObject,pSubName)) { - if (getMainWindow()) { -<<<<<<< 18faa737da36035dd5ff84b1a5e26e38fd5194e1 - getMainWindow()->showMessage(QString::fromLatin1("Selection not allowed by filter"),5000); -======= - QString msg; - if (ActiveGate->notAllowedReason.length() > 0) { - msg = QObject::tr(ActiveGate->notAllowedReason.c_str()); - } else { - msg = QCoreApplication::translate("SelectionFilter","Selection not allowed by filter"); - } - getMainWindow()->showMessage(msg,5000); ->>>>>>> SelectionGate: add capability to display why not allowed. - Gui::MDIView* mdi = Gui::Application::Instance->activeDocument()->getActiveView(); - mdi->setOverrideCursor(Qt::ForbiddenCursor); - } - ActiveGate->notAllowedReason.clear(); - QApplication::beep(); - return false; - } - } - - temp.DocName = pDocName; - temp.FeatName = pObjectName ? pObjectName : ""; - temp.SubName = pSubName ? pSubName : ""; - temp.x = x; - temp.y = y; - temp.z = z; - - if (temp.pObject) - temp.TypeName = temp.pObject->getTypeId().getName(); - - _SelList.push_back(temp); - - SelectionChanges Chng; - - Chng.pDocName = pDocName; - Chng.pObjectName = pObjectName ? pObjectName : ""; - Chng.pSubName = pSubName ? pSubName : ""; - Chng.x = x; - Chng.y = y; - Chng.z = z; - Chng.Type = SelectionChanges::AddSelection; - - - Notify(Chng); - signalSelectionChanged(Chng); - - Base::Console().Log("Sel : Add Selection \"%s.%s.%s(%f,%f,%f)\"\n",pDocName,pObjectName,pSubName,x,y,z); - - // allow selection - return true; - } - else { - // neither an existing nor active document available - // this can often happen when importing .iv files - Base::Console().Error("Cannot add to selection: no document '%s' found.\n", pDocName); - return false; - } -} - -bool SelectionSingleton::addSelection(const char* pDocName, const char* pObjectName, const std::vector& pSubNames) -{ - // already in ? - //if (isSelected(pDocName, pObjectName, pSubName)) - // return true; - - _SelObj temp; - - temp.pDoc = getDocument(pDocName); - - if (temp.pDoc) { - if(pObjectName) - temp.pObject = temp.pDoc->getObject(pObjectName); - else - temp.pObject = 0; - - if (temp.pObject) - temp.TypeName = temp.pObject->getTypeId().getName(); - - temp.DocName = pDocName; - temp.FeatName = pObjectName ? pObjectName : ""; - for (std::vector::const_iterator it = pSubNames.begin(); it != pSubNames.end(); ++it) { - temp.SubName = it->c_str(); - temp.x = 0; - temp.y = 0; - temp.z = 0; - - _SelList.push_back(temp); - } - - SelectionChanges Chng; - - Chng.pDocName = pDocName; - Chng.pObjectName = pObjectName ? pObjectName : ""; - Chng.pSubName = ""; - Chng.x = 0; - Chng.y = 0; - Chng.z = 0; - Chng.Type = SelectionChanges::AddSelection; - - Notify(Chng); - signalSelectionChanged(Chng); - - // allow selection - return true; - } - else { - // neither an existing nor active document available - // this can often happen when importing .iv files - Base::Console().Error("Cannot add to selection: no document '%s' found.\n", pDocName); - return false; - } -} - -void SelectionSingleton::rmvSelection(const char* pDocName, const char* pObjectName, const char* pSubName) -{ - std::vector rmvList; - - for (std::list<_SelObj>::iterator It = _SelList.begin();It != _SelList.end();) { - if ((It->DocName == pDocName && !pObjectName) || - (It->DocName == pDocName && pObjectName && It->FeatName == pObjectName && !pSubName) || - (It->DocName == pDocName && pObjectName && It->FeatName == pObjectName && pSubName && It->SubName == pSubName)) - { - // save in tmp. string vars - std::string tmpDocName = It->DocName; - std::string tmpFeaName = It->FeatName; - std::string tmpSubName = It->SubName; - - // destroy the _SelObj item - It = _SelList.erase(It); - - SelectionChanges Chng; - Chng.pDocName = tmpDocName.c_str(); - Chng.pObjectName = tmpFeaName.c_str(); - Chng.pSubName = tmpSubName.c_str(); - Chng.Type = SelectionChanges::RmvSelection; - - Notify(Chng); - signalSelectionChanged(Chng); - - rmvList.push_back(Chng); - Base::Console().Log("Sel : Rmv Selection \"%s.%s.%s\"\n",pDocName,pObjectName,pSubName); - } - else { - ++It; - } - } -} - -void SelectionSingleton::setSelection(const char* pDocName, const std::vector& sel) -{ - App::Document *pcDoc; - pcDoc = getDocument(pDocName); - if (!pcDoc) - return; - - std::set cur_sel, new_sel; - new_sel.insert(sel.begin(), sel.end()); - - // Make sure to keep the order of the currently selected objects - std::list<_SelObj> temp; - for (std::list<_SelObj>::const_iterator it = _SelList.begin(); it != _SelList.end(); ++it) { - if (it->pDoc != pcDoc) - temp.push_back(*it); - else { - cur_sel.insert(it->pObject); - if (new_sel.find(it->pObject) != new_sel.end()) - temp.push_back(*it); - } - } - - // Get the objects we must add to the selection - std::vector diff_new_cur; - std::back_insert_iterator< std::vector > biit(diff_new_cur); - std::set_difference(new_sel.begin(), new_sel.end(), cur_sel.begin(), cur_sel.end(), biit); - - _SelObj obj; - for (std::vector::const_iterator it = diff_new_cur.begin(); it != diff_new_cur.end(); ++it) { - obj.pDoc = pcDoc; - obj.pObject = *it; - obj.DocName = pDocName; - obj.FeatName = (*it)->getNameInDocument(); - obj.SubName = ""; - obj.TypeName = (*it)->getTypeId().getName(); - obj.x = 0.0f; - obj.y = 0.0f; - obj.z = 0.0f; - temp.push_back(obj); - } - - if (cur_sel == new_sel) // nothing has changed - return; - - _SelList = temp; - - SelectionChanges Chng; - Chng.Type = SelectionChanges::SetSelection; - Chng.pDocName = pDocName; - Chng.pObjectName = ""; - Chng.pSubName = ""; - - Notify(Chng); - signalSelectionChanged(Chng); -} - -void SelectionSingleton::clearSelection(const char* pDocName) -{ - App::Document* pDoc; - pDoc = getDocument(pDocName); - - // the document 'pDocName' has already been removed - if (!pDoc && !pDocName) { - clearCompleteSelection(); - } - else { - std::string docName; - if (pDocName) - docName = pDocName; - else - docName = pDoc->getName(); // active document - std::list<_SelObj> selList; - for (std::list<_SelObj>::iterator it = _SelList.begin(); it != _SelList.end(); ++it) { - if (it->DocName != docName) - selList.push_back(*it); - } - - _SelList = selList; - - SelectionChanges Chng; - Chng.Type = SelectionChanges::ClrSelection; - Chng.pDocName = docName.c_str(); - Chng.pObjectName = ""; - Chng.pSubName = ""; - - Notify(Chng); - signalSelectionChanged(Chng); - - Base::Console().Log("Sel : Clear selection\n"); - } -} - -void SelectionSingleton::clearCompleteSelection() -{ - _SelList.clear(); - - SelectionChanges Chng; - Chng.Type = SelectionChanges::ClrSelection; - Chng.pDocName = ""; - Chng.pObjectName = ""; - Chng.pSubName = ""; - - - Notify(Chng); - signalSelectionChanged(Chng); - - Base::Console().Log("Sel : Clear selection\n"); -} - -bool SelectionSingleton::isSelected(const char* pDocName, const char* pObjectName, const char* pSubName) const -{ - const char* tmpDocName = pDocName ? pDocName : ""; - const char* tmpFeaName = pObjectName ? pObjectName : ""; - const char* tmpSubName = pSubName ? pSubName : ""; - for (std::list<_SelObj>::const_iterator It = _SelList.begin();It != _SelList.end();++It) - if (It->DocName == tmpDocName && It->FeatName == tmpFeaName && It->SubName == tmpSubName) - return true; - return false; -} - -bool SelectionSingleton::isSelected(App::DocumentObject* obj, const char* pSubName) const -{ - if (!obj) return false; - - for(list<_SelObj>::const_iterator It = _SelList.begin();It != _SelList.end();++It) { - if (It->pObject == obj) { - if (pSubName) { - if (It->SubName == pSubName) - return true; - } - else { - return true; - } - } - } - - return false; -} - -void SelectionSingleton::slotDeletedObject(const App::DocumentObject& Obj) -{ - // remove also from the selection, if selected - Selection().rmvSelection( Obj.getDocument()->getName(), Obj.getNameInDocument() ); -} - - -//************************************************************************** -// Construction/Destruction - -/** - * A constructor. - * A more elaborate description of the constructor. - */ -SelectionSingleton::SelectionSingleton() -{ - ActiveGate = 0; - App::GetApplication().signalDeletedObject.connect(boost::bind(&Gui::SelectionSingleton::slotDeletedObject, this, _1)); - CurrentPreselection.pDocName = 0; - CurrentPreselection.pObjectName = 0; - CurrentPreselection.pSubName = 0; - -} - -/** - * A destructor. - * A more elaborate description of the destructor. - */ -SelectionSingleton::~SelectionSingleton() -{ -} - -SelectionSingleton* SelectionSingleton::_pcSingleton = NULL; - -SelectionSingleton& SelectionSingleton::instance(void) -{ - if (_pcSingleton == NULL) - _pcSingleton = new SelectionSingleton; - return *_pcSingleton; -} - -void SelectionSingleton::destruct (void) -{ - if (_pcSingleton != NULL) - delete _pcSingleton; - _pcSingleton = 0; -} - -//************************************************************************** -// Python stuff - -// SelectionSingleton Methods // Methods structure -PyMethodDef SelectionSingleton::Methods[] = { - {"addSelection", (PyCFunction) SelectionSingleton::sAddSelection, 1, - "addSelection(object,[string,float,float,float]) -- Add an object to the selection\n" - "where string is the sub-element name and the three floats represent a 3d point"}, - {"removeSelection", (PyCFunction) SelectionSingleton::sRemoveSelection, 1, - "removeSelection(object) -- Remove an object from the selection"}, - {"clearSelection" , (PyCFunction) SelectionSingleton::sClearSelection, 1, - "clearSelection([string]) -- Clear the selection\n" - "Clear the selection to the given document name. If no document is\n" - "given the complete selection is cleared."}, - {"isSelected", (PyCFunction) SelectionSingleton::sIsSelected, 1, - "isSelected(object) -- Check if a given object is selected"}, - {"countObjectsOfType", (PyCFunction) SelectionSingleton::sCountObjectsOfType, 1, - "countObjectsOfType(string, [string]) -- Get the number of selected objects\n" - "The first argument defines the object type e.g. \"Part::Feature\" and the\n" - "second argumeht defines the document name. If no document name is given the\n" - "currently active document is used"}, - {"getSelection", (PyCFunction) SelectionSingleton::sGetSelection, 1, - "getSelection([string]) -- Return a list of selected objets\n" - "Return a list of selected objects for a given document name. If no\n" - "document name is given the selection for the active document is returned."}, - {"getCompleteSelection", (PyCFunction) SelectionSingleton::sGetCompleteSelection, 1, - "getCompleteSelection() -- Return a list of selected objects of all documents."}, - {"getSelectionEx", (PyCFunction) SelectionSingleton::sGetSelectionEx, 1, - "getSelectionEx([string]) -- Return a list of SelectionObjects\n" - "Return a list of SelectionObjects for a given document name. If no\n" - "document is given the selection of the active document is returned.\n" - "The SelectionObjects contain a variety of information about the selection,\n" - "e.g. sub-element names."}, - {"getSelectionObject", (PyCFunction) SelectionSingleton::sGetSelectionObject, 1, - "getSelectionObject(doc,obj,sub,(x,y,z)) -- Return a SelectionObject"}, - {"addObserver", (PyCFunction) SelectionSingleton::sAddSelObserver, 1, - "addObserver(Object) -- Install an observer\n"}, - {"removeObserver", (PyCFunction) SelectionSingleton::sRemSelObserver, 1, - "removeObserver(Object) -- Uninstall an observer\n"}, - {"addSelectionGate", (PyCFunction) SelectionSingleton::sAddSelectionGate, 1, - "addSelectionGate(String|Filter|Gate) -- activate the selection gate.\n" - "The selection gate will prohibit all selections which do not match\n" - "the given selection filter string.\n" - " Examples strings are:\n" - "'SELECT Part::Feature SUBELEMENT Edge',\n" - "'SELECT Robot::RobotObject'\n" - "\n" - "You can also set an instance of SelectionFilter:\n" - "filter = Gui.Selection.Filter('SELECT Part::Feature SUBELEMENT Edge')\n" - "Gui.Selection.addSelectionGate(filter)\n" - "\n" - "And the most flexible approach is to write your own selection gate class\n" - "that implements the method 'allow'\n" - "class Gate:\n" - " def allow(self,doc,obj,sub):\n" - " return (sub[0:4] == 'Face')\n" - "Gui.Selection.addSelectionGate(Gate())"}, - {"removeSelectionGate", (PyCFunction) SelectionSingleton::sRemoveSelectionGate, 1, - "removeSelectionGate() -- remove the active selection gate\n"}, - {NULL, NULL, 0, NULL} /* Sentinel */ -}; - -PyObject *SelectionSingleton::sAddSelection(PyObject * /*self*/, PyObject *args, PyObject * /*kwd*/) -{ - PyObject *object; - char* subname=0; - float x=0,y=0,z=0; - if (!PyArg_ParseTuple(args, "O!|sfff", &(App::DocumentObjectPy::Type),&object,&subname,&x,&y,&z)) - return NULL; // NULL triggers exception - - App::DocumentObjectPy* docObjPy = static_cast(object); - App::DocumentObject* docObj = docObjPy->getDocumentObjectPtr(); - if (!docObj || !docObj->getNameInDocument()) { - PyErr_SetString(Base::BaseExceptionFreeCADError, "Cannot check invalid object"); - return NULL; - } - - Selection().addSelection(docObj->getDocument()->getName(), - docObj->getNameInDocument(), - subname,x,y,z); - - Py_Return; -} - -PyObject *SelectionSingleton::sRemoveSelection(PyObject * /*self*/, PyObject *args, PyObject * /*kwd*/) -{ - PyObject *object; - char* subname=0; - if (!PyArg_ParseTuple(args, "O!|s", &(App::DocumentObjectPy::Type),&object,&subname)) - return NULL; // NULL triggers exception - - App::DocumentObjectPy* docObjPy = static_cast(object); - App::DocumentObject* docObj = docObjPy->getDocumentObjectPtr(); - if (!docObj || !docObj->getNameInDocument()) { - PyErr_SetString(Base::BaseExceptionFreeCADError, "Cannot check invalid object"); - return NULL; - } - - Selection().rmvSelection(docObj->getDocument()->getName(), - docObj->getNameInDocument(), - subname); - - Py_Return; -} - -PyObject *SelectionSingleton::sClearSelection(PyObject * /*self*/, PyObject *args, PyObject * /*kwd*/) -{ - char *documentName=0; - if (!PyArg_ParseTuple(args, "|s", &documentName)) // convert args: Python->C - return NULL; // NULL triggers exception - documentName ? Selection().clearSelection(documentName) : Selection().clearCompleteSelection(); - Py_Return; -} - -PyObject *SelectionSingleton::sIsSelected(PyObject * /*self*/, PyObject *args, PyObject * /*kwd*/) -{ - PyObject *object; - char* subname=0; - if (!PyArg_ParseTuple(args, "O!|s", &(App::DocumentObjectPy::Type), &object, &subname)) - return NULL; // NULL triggers exception - - App::DocumentObjectPy* docObj = static_cast(object); - bool ok = Selection().isSelected(docObj->getDocumentObjectPtr(), subname); - return Py_BuildValue("O", (ok ? Py_True : Py_False)); -} - -PyObject *SelectionSingleton::sCountObjectsOfType(PyObject * /*self*/, PyObject *args, PyObject * /*kwd*/) -{ - char* objecttype; - char* document=0; - if (!PyArg_ParseTuple(args, "s|s", &objecttype, &document)) - return NULL; - - unsigned int count = Selection().countObjectsOfType(objecttype, document); - return PyInt_FromLong(count); -} - -PyObject *SelectionSingleton::sGetSelection(PyObject * /*self*/, PyObject *args, PyObject * /*kwd*/) -{ - char *documentName=0; - if (!PyArg_ParseTuple(args, "|s", &documentName)) // convert args: Python->C - return NULL; // NULL triggers exception - - std::vector sel; - sel = Selection().getSelection(documentName); - - try { - Py::List list; - for (std::vector::iterator it = sel.begin(); it != sel.end(); ++it) { - list.append(Py::asObject(it->pObject->getPyObject())); - } - return Py::new_reference_to(list); - } - catch (Py::Exception&) { - return 0; - } -} - -PyObject *SelectionSingleton::sGetCompleteSelection(PyObject * /*self*/, PyObject *args, PyObject * /*kwd*/) -{ - if (!PyArg_ParseTuple(args, "")) // convert args: Python->C - return NULL; // NULL triggers exception - - std::vector sel; - sel = Selection().getCompleteSelection(); - - try { - Py::List list; - for (std::vector::iterator it = sel.begin(); it != sel.end(); ++it) { - list.append(Py::asObject(it->pObject->getPyObject())); - } - return Py::new_reference_to(list); - } - catch (Py::Exception&) { - return 0; - } -} - -PyObject *SelectionSingleton::sGetSelectionEx(PyObject * /*self*/, PyObject *args, PyObject * /*kwd*/) -{ - char *documentName=0; - if (!PyArg_ParseTuple(args, "|s", &documentName)) // convert args: Python->C - return NULL; // NULL triggers exception - - std::vector sel; - sel = Selection().getSelectionEx(documentName); - - try { - Py::List list; - for (std::vector::iterator it = sel.begin(); it != sel.end(); ++it) { - list.append(Py::asObject(it->getPyObject())); - } - return Py::new_reference_to(list); - } - catch (Py::Exception&) { - return 0; - } -} - -PyObject *SelectionSingleton::sGetSelectionObject(PyObject * /*self*/, PyObject *args, PyObject * /*kwd*/) -{ - char *docName, *objName, *subName; - PyObject* tuple=0; - if (!PyArg_ParseTuple(args, "sss|O!", &docName, &objName, &subName, - &PyTuple_Type, &tuple)) - return NULL; - - try { - SelectionObject selObj; - selObj.DocName = docName; - selObj.FeatName = objName; - std::string sub = subName; - if (!sub.empty()) { - selObj.SubNames.push_back(sub); - if (tuple) { - Py::Tuple t(tuple); - double x = (double)Py::Float(t.getItem(0)); - double y = (double)Py::Float(t.getItem(1)); - double z = (double)Py::Float(t.getItem(2)); - selObj.SelPoses.push_back(Base::Vector3d(x,y,z)); - } - } - - return selObj.getPyObject(); - } - catch (const Py::Exception&) { - return 0; - } - catch (const Base::Exception& e) { - PyErr_SetString(Base::BaseExceptionFreeCADError, e.what()); - return 0; - } -} - -PyObject *SelectionSingleton::sAddSelObserver(PyObject * /*self*/, PyObject *args, PyObject * /*kwd*/) -{ - PyObject* o; - if (!PyArg_ParseTuple(args, "O",&o)) - return NULL; - PY_TRY { - SelectionObserverPython::addObserver(Py::Object(o)); - Py_Return; - } PY_CATCH; -} - -PyObject *SelectionSingleton::sRemSelObserver(PyObject * /*self*/, PyObject *args, PyObject * /*kwd*/) -{ - PyObject* o; - if (!PyArg_ParseTuple(args, "O",&o)) - return NULL; - PY_TRY { - SelectionObserverPython::removeObserver(Py::Object(o)); - Py_Return; - } PY_CATCH; -} - -PyObject *SelectionSingleton::sAddSelectionGate(PyObject * /*self*/, PyObject *args, PyObject * /*kwd*/) -{ - char* filter; - if (PyArg_ParseTuple(args, "s",&filter)) { - PY_TRY { - Selection().addSelectionGate(new SelectionFilterGate(filter)); - Py_Return; - } PY_CATCH; - } - - PyErr_Clear(); - PyObject* filterPy; - if (PyArg_ParseTuple(args, "O!",SelectionFilterPy::type_object(),&filterPy)) { - PY_TRY { - Selection().addSelectionGate(new SelectionFilterGatePython(static_cast(filterPy))); - Py_Return; - } PY_CATCH; - } - - PyErr_Clear(); - PyObject* gate; - if (PyArg_ParseTuple(args, "O",&gate)) { - PY_TRY { - Selection().addSelectionGate(new SelectionGatePython(Py::Object(gate, false))); - Py_Return; - } PY_CATCH; - } - - PyErr_SetString(PyExc_ValueError, "Argument is neither string nor SelectionFiler nor SelectionGate"); - return 0; -} - -PyObject *SelectionSingleton::sRemoveSelectionGate(PyObject * /*self*/, PyObject *args, PyObject * /*kwd*/) -{ - if (!PyArg_ParseTuple(args, "")) - return NULL; // NULL triggers exception - - PY_TRY { - Selection().rmvSelectionGate(); - } PY_CATCH; - - Py_Return; -} diff --git a/src/Gui/View3DInventorViewer.cpp.orig b/src/Gui/View3DInventorViewer.cpp.orig deleted file mode 100644 index a078cf556..000000000 --- a/src/Gui/View3DInventorViewer.cpp.orig +++ /dev/null @@ -1,2759 +0,0 @@ -/*************************************************************************** - * Copyright (c) 2004 Juergen Riegel * - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file COPYING.LIB. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * - ***************************************************************************/ - - -#include "PreCompiled.h" -#ifndef _PreComp_ -# include -# ifdef FC_OS_WIN32 -# include -# endif -# ifdef FC_OS_MACOSX -# include -# else -# include -# endif -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -#endif - -#include -#include -#include -#include -#include -#include - -#include "View3DInventorViewer.h" -#include "ViewProviderDocumentObject.h" -#include "SoFCBackgroundGradient.h" -#include "SoFCColorBar.h" -#include "SoFCColorLegend.h" -#include "SoFCColorGradient.h" -#include "SoFCOffscreenRenderer.h" -#include "SoFCSelection.h" -#include "SoFCUnifiedSelection.h" -#include "SoFCInteractiveElement.h" -#include "SoFCBoundingBox.h" -#include "SoAxisCrossKit.h" -#include "View3DInventorRiftViewer.h" - -#include "Selection.h" -#include "SoFCSelectionAction.h" -#include "SoFCVectorizeU3DAction.h" -#include "SoFCVectorizeSVGAction.h" -#include "SoFCDB.h" -#include "Application.h" -#include "MainWindow.h" -#include "NavigationStyle.h" -#include "ViewProvider.h" -#include "SpaceballEvent.h" -#include "GLPainter.h" -#include -#include -#include "View3DViewerPy.h" - -#include -#include -#include - -#include "SoTouchEvents.h" -#include "WinNativeGestureRecognizers.h" - -//#define FC_LOGGING_CB - -using namespace Gui; - -/*** zoom-style cursor ******/ - -#define ZOOM_WIDTH 16 -#define ZOOM_HEIGHT 16 -#define ZOOM_BYTES ((ZOOM_WIDTH + 7) / 8) * ZOOM_HEIGHT -#define ZOOM_HOT_X 5 -#define ZOOM_HOT_Y 7 - -static unsigned char zoom_bitmap[ZOOM_BYTES] = -{ - 0x00, 0x0f, 0x80, 0x1c, 0x40, 0x38, 0x20, 0x70, - 0x90, 0xe4, 0xc0, 0xcc, 0xf0, 0xfc, 0x00, 0x0c, - 0x00, 0x0c, 0xf0, 0xfc, 0xc0, 0xcc, 0x90, 0xe4, - 0x20, 0x70, 0x40, 0x38, 0x80, 0x1c, 0x00, 0x0f -}; - -static unsigned char zoom_mask_bitmap[ZOOM_BYTES] = -{ - 0x00,0x0f,0x80,0x1f,0xc0,0x3f,0xe0,0x7f,0xf0,0xff,0xf0,0xff,0xf0,0xff,0x00, - 0x0f,0x00,0x0f,0xf0,0xff,0xf0,0xff,0xf0,0xff,0xe0,0x7f,0xc0,0x3f,0x80,0x1f, - 0x00,0x0f -}; - -/*** pan-style cursor *******/ - -#define PAN_WIDTH 16 -#define PAN_HEIGHT 16 -#define PAN_BYTES ((PAN_WIDTH + 7) / 8) * PAN_HEIGHT -#define PAN_HOT_X 7 -#define PAN_HOT_Y 7 - -static unsigned char pan_bitmap[PAN_BYTES] = -{ - 0xc0, 0x03, 0x60, 0x02, 0x20, 0x04, 0x10, 0x08, - 0x68, 0x16, 0x54, 0x2a, 0x73, 0xce, 0x01, 0x80, - 0x01, 0x80, 0x73, 0xce, 0x54, 0x2a, 0x68, 0x16, - 0x10, 0x08, 0x20, 0x04, 0x40, 0x02, 0xc0, 0x03 -}; - -static unsigned char pan_mask_bitmap[PAN_BYTES] = -{ - 0xc0,0x03,0xe0,0x03,0xe0,0x07,0xf0,0x0f,0xe8,0x17,0xdc,0x3b,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xdc,0x3b,0xe8,0x17,0xf0,0x0f,0xe0,0x07,0xc0,0x03, - 0xc0,0x03 -}; - -/*** rotate-style cursor ****/ - -#define ROTATE_WIDTH 16 -#define ROTATE_HEIGHT 16 -#define ROTATE_BYTES ((ROTATE_WIDTH + 7) / 8) * ROTATE_HEIGHT -#define ROTATE_HOT_X 6 -#define ROTATE_HOT_Y 8 - -static unsigned char rotate_bitmap[ROTATE_BYTES] = { - 0xf0, 0xef, 0x18, 0xb8, 0x0c, 0x90, 0xe4, 0x83, - 0x34, 0x86, 0x1c, 0x83, 0x00, 0x81, 0x00, 0xff, - 0xff, 0x00, 0x81, 0x00, 0xc1, 0x38, 0x61, 0x2c, - 0xc1, 0x27, 0x09, 0x30, 0x1d, 0x18, 0xf7, 0x0f -}; - -static unsigned char rotate_mask_bitmap[ROTATE_BYTES] = { - 0xf0,0xef,0xf8,0xff,0xfc,0xff,0xfc,0xff,0x3c,0xfe,0x1c,0xff,0x00,0xff,0x00, - 0xff,0xff,0x00,0xff,0x00,0xff,0x38,0x7f,0x3c,0xff,0x3f,0xff,0x3f,0xff,0x1f, - 0xf7,0x0f -}; - - -/*! -As ProgressBar has no chance to control the incoming Qt events of Quarter so we need to stop -the event handling to prevent the scenegraph from being selected or deselected -while the progress bar is running. -*/ -class Gui::ViewerEventFilter : public QObject -{ -public: - ViewerEventFilter() {} - ~ViewerEventFilter() {} - - - - bool eventFilter(QObject* obj, QEvent* event) { - -#ifdef GESTURE_MESS - if (obj->isWidgetType()) { - View3DInventorViewer* v = dynamic_cast(obj); - if(v) { - /* Internally, Qt seems to set up the gestures upon showing the - * widget (but after this event is processed), thus invalidating - * our settings. This piece takes care to retune gestures on the - * next event after the show event. - */ - if(v->winGestureTuneState == View3DInventorViewer::ewgtsNeedTuning) { - try{ - WinNativeGestureRecognizerPinch::TuneWindowsGestures(v); - v->winGestureTuneState = View3DInventorViewer::ewgtsTuned; - } catch (Base::Exception &e) { - Base::Console().Warning("Failed to TuneWindowsGestures. Error: %s\n",e.what()); - v->winGestureTuneState = View3DInventorViewer::ewgtsDisabled; - } catch (...) { - Base::Console().Warning("Failed to TuneWindowsGestures. Unknown error.\n"); - v->winGestureTuneState = View3DInventorViewer::ewgtsDisabled; - } - } - if (event->type() == QEvent::Show && v->winGestureTuneState == View3DInventorViewer::ewgtsTuned) - v->winGestureTuneState = View3DInventorViewer::ewgtsNeedTuning; - - } - } -#endif - - // Bug #0000607: Some mices also support horizontal scrolling which however might - // lead to some unwanted zooming when pressing the MMB for panning. - // Thus, we filter out horizontal scrolling. - if (event->type() == QEvent::Wheel) { - QWheelEvent* we = static_cast(event); - if (we->orientation() == Qt::Horizontal) - return true; - } - else if (event->type() == QEvent::KeyPress) { - QKeyEvent* ke = static_cast(event); - if (ke->matches(QKeySequence::SelectAll)) { - static_cast(obj)->selectAll(); - return true; - } - } - if (Base::Sequencer().isRunning() && Base::Sequencer().isBlocking()) - return false; - - if (event->type() == Spaceball::ButtonEvent::ButtonEventType) { - Spaceball::ButtonEvent* buttonEvent = static_cast(event); - if (!buttonEvent) { - Base::Console().Log("invalid spaceball button event\n"); - return true; - } - } - else if (event->type() == Spaceball::MotionEvent::MotionEventType) { - Spaceball::MotionEvent* motionEvent = static_cast(event); - if (!motionEvent) { - Base::Console().Log("invalid spaceball motion event\n"); - return true; - } - } - - return false; - } -}; - -class SpaceNavigatorDevice : public Quarter::InputDevice { -public: - SpaceNavigatorDevice(void) {} - virtual ~SpaceNavigatorDevice() {} - virtual const SoEvent* translateEvent(QEvent* event) { - - if (event->type() == Spaceball::MotionEvent::MotionEventType) { - Spaceball::MotionEvent* motionEvent = static_cast(event); - if (!motionEvent) { - Base::Console().Log("invalid spaceball motion event\n"); - return NULL; - } - - motionEvent->setHandled(true); - - float xTrans, yTrans, zTrans; - xTrans = static_cast(motionEvent->translationX()); - yTrans = static_cast(motionEvent->translationY()); - zTrans = static_cast(motionEvent->translationZ()); - SbVec3f translationVector(xTrans, yTrans, zTrans); - - static float rotationConstant(.0001f); - SbRotation xRot, yRot, zRot; - xRot.setValue(SbVec3f(1.0, 0.0, 0.0), static_cast(motionEvent->rotationX()) * rotationConstant); - yRot.setValue(SbVec3f(0.0, 1.0, 0.0), static_cast(motionEvent->rotationY()) * rotationConstant); - zRot.setValue(SbVec3f(0.0, 0.0, 1.0), static_cast(motionEvent->rotationZ()) * rotationConstant); - - SoMotion3Event* motion3Event = new SoMotion3Event; - motion3Event->setTranslation(translationVector); - motion3Event->setRotation(xRot * yRot * zRot); - - return motion3Event; - } - - return NULL; - }; -}; - -/** \defgroup View3D 3D Viewer - * \ingroup GUI - * - * The 3D Viewer is one of the major components in a CAD/CAE systems. - * Therefore an overview and some remarks to the FreeCAD 3D viewing system. - * - * \section overview Overview - * \todo Overview and complements for the 3D Viewer - */ - - -// ************************************************************************* -View3DInventorViewer::View3DInventorViewer(QWidget* parent, const QGLWidget* sharewidget) - : Quarter::SoQTQuarterAdaptor(parent, sharewidget), editViewProvider(0), navigation(0), - renderType(Native), framebuffer(0), axisCross(0), axisGroup(0), editing(false), redirected(false), - allowredir(false), overrideMode("As Is"), _viewerPy(0) -{ - init(); -} - -View3DInventorViewer::View3DInventorViewer(const QGLFormat& format, QWidget* parent, const QGLWidget* sharewidget) - : Quarter::SoQTQuarterAdaptor(format, parent, sharewidget), editViewProvider(0), navigation(0), - renderType(Native), framebuffer(0), axisCross(0), axisGroup(0), editing(false), redirected(false), - allowredir(false), overrideMode("As Is"), _viewerPy(0) -{ - init(); -} - -void View3DInventorViewer::init() -{ - Gui::Selection().Attach(this); - - // Coin should not clear the pixel-buffer, so the background image - // is not removed. - this->setClearWindow(false); - - // setting up the defaults for the spin rotation - initialize(); - - SoOrthographicCamera* cam = new SoOrthographicCamera; - cam->position = SbVec3f(0, 0, 1); - cam->height = 1; - cam->nearDistance = 0.5; - cam->farDistance = 1.5; - - // setup light sources - SoDirectionalLight* hl = this->getHeadlight(); - backlight = new SoDirectionalLight(); - backlight->ref(); - backlight->setName("backlight"); - backlight->direction.setValue(-hl->direction.getValue()); - backlight->on.setValue(false); // by default off - - // Set up background scenegraph with image in it. - backgroundroot = new SoSeparator; - backgroundroot->ref(); - this->backgroundroot->addChild(cam); - - // Background stuff - pcBackGround = new SoFCBackgroundGradient; - pcBackGround->ref(); - - // Set up foreground, overlayed scenegraph. - this->foregroundroot = new SoSeparator; - this->foregroundroot->ref(); - - SoLightModel* lm = new SoLightModel; - lm->model = SoLightModel::BASE_COLOR; - - SoBaseColor* bc = new SoBaseColor; - bc->rgb = SbColor(1, 1, 0); - - cam = new SoOrthographicCamera; - cam->position = SbVec3f(0, 0, 5); - cam->height = 10; - cam->nearDistance = 0; - cam->farDistance = 10; - - // dragger - //SoSeparator * dragSep = new SoSeparator(); - //SoScale *scale = new SoScale(); - //scale->scaleFactor = SbVec3f (0.2,0.2,0.2); - //dragSep->addChild(scale); - //SoCenterballDragger *dragger = new SoCenterballDragger(); - //dragger->center = SbVec3f (0.8,0.8,0); - ////dragger->rotation = SbRotation(rrot[0],rrot[1],rrot[2],rrot[3]); - //dragSep->addChild(dragger); - - this->foregroundroot->addChild(cam); - this->foregroundroot->addChild(lm); - this->foregroundroot->addChild(bc); - //this->foregroundroot->addChild(dragSep); - -#if 0 - // NOTE: For every mouse click event the SoSelection searches for the picked - // point which causes a certain slow-down because for all objects the primitives - // must be created. Using an SoSeparator avoids this drawback. - SoSelection* selectionRoot = new SoSelection(); - selectionRoot->addSelectionCallback(View3DInventorViewer::selectCB, this); - selectionRoot->addDeselectionCallback(View3DInventorViewer::deselectCB, this); - selectionRoot->setPickFilterCallback(View3DInventorViewer::pickFilterCB, this); -#else - // NOTE: For every mouse click event the SoFCUnifiedSelection searches for the picked - // point which causes a certain slow-down because for all objects the primitives - // must be created. Using an SoSeparator avoids this drawback. - selectionRoot = new Gui::SoFCUnifiedSelection(); - selectionRoot->applySettings(); -#endif - // set the ViewProvider root node - pcViewProviderRoot = selectionRoot; - - // increase refcount before passing it to setScenegraph(), to avoid - // premature destruction - pcViewProviderRoot->ref(); - // is not really working with Coin3D. - //redrawOverlayOnSelectionChange(pcSelection); - setSceneGraph(pcViewProviderRoot); - // Event callback node - pEventCallback = new SoEventCallback(); - pEventCallback->setUserData(this); - pEventCallback->ref(); - pcViewProviderRoot->addChild(pEventCallback); - pEventCallback->addEventCallback(SoEvent::getClassTypeId(), handleEventCB, this); - - dimensionRoot = new SoSwitch(SO_SWITCH_NONE); - pcViewProviderRoot->addChild(dimensionRoot); - dimensionRoot->addChild(new SoSwitch()); //first one will be for the 3d dimensions. - dimensionRoot->addChild(new SoSwitch()); //second one for the delta dimensions. - - // This is a callback node that logs all action that traverse the Inventor tree. -#if defined (FC_DEBUG) && defined(FC_LOGGING_CB) - SoCallback* cb = new SoCallback; - cb->setCallback(interactionLoggerCB, this); - pcViewProviderRoot->addChild(cb); -#endif - - // Set our own render action which show a bounding box if - // the SoFCSelection::BOX style is set - // - // Important note: - // When creating a new GL render action we have to copy over the cache context id - // because otherwise we may get strange rendering behaviour. For more details see - // http://forum.freecadweb.org/viewtopic.php?f=10&t=7486&start=120#p74398 and for - // the fix and some details what happens behind the scene have a look at this - // http://forum.freecadweb.org/viewtopic.php?f=10&t=7486&p=74777#p74736 - uint32_t id = this->getSoRenderManager()->getGLRenderAction()->getCacheContext(); - this->getSoRenderManager()->setGLRenderAction(new SoBoxSelectionRenderAction); - this->getSoRenderManager()->getGLRenderAction()->setCacheContext(id); - - // set the transperency and antialiasing settings -// getGLRenderAction()->setTransparencyType(SoGLRenderAction::SORTED_OBJECT_BLEND); - getSoRenderManager()->getGLRenderAction()->setTransparencyType(SoGLRenderAction::SORTED_OBJECT_SORTED_TRIANGLE_BLEND); -// getGLRenderAction()->setSmoothing(true); - - // Settings - setSeekTime(0.4f); - - if(isSeekValuePercentage() == false) - setSeekValueAsPercentage(true); - - setSeekDistance(100); - setViewing(false); - - setBackgroundColor(QColor(25, 25, 25)); - setGradientBackground(true); - - // set some callback functions for user interaction - addStartCallback(interactionStartCB); - addFinishCallback(interactionFinishCB); - - //filter a few qt events - viewerEventFilter = new ViewerEventFilter; - installEventFilter(viewerEventFilter); - getEventFilter()->registerInputDevice(new SpaceNavigatorDevice); - getEventFilter()->registerInputDevice(new GesturesDevice(this)); - - this->winGestureTuneState = View3DInventorViewer::ewgtsDisabled; - try{ - this->grabGesture(Qt::PanGesture); - this->grabGesture(Qt::PinchGesture); - #ifdef GESTURE_MESS - { - static WinNativeGestureRecognizerPinch* recognizer;//static to avoid creating more than one recognizer, thus causing memory leak and gradual slowdown - if(recognizer == 0){ - recognizer = new WinNativeGestureRecognizerPinch; - recognizer->registerRecognizer(recognizer); //From now on, Qt owns the pointer. - } - } - this->winGestureTuneState = View3DInventorViewer::ewgtsNeedTuning; - #endif - } catch (Base::Exception &e) { - Base::Console().Warning("Failed to set up gestures. Error: %s\n", e.what()); - } catch (...) { - Base::Console().Warning("Failed to set up gestures. Unknown error.\n"); - } - - //create the cursors - QBitmap cursor = QBitmap::fromData(QSize(ROTATE_WIDTH, ROTATE_HEIGHT), rotate_bitmap); - QBitmap mask = QBitmap::fromData(QSize(ROTATE_WIDTH, ROTATE_HEIGHT), rotate_mask_bitmap); - spinCursor = QCursor(cursor, mask, ROTATE_HOT_X, ROTATE_HOT_Y); - - cursor = QBitmap::fromData(QSize(ZOOM_WIDTH, ZOOM_HEIGHT), zoom_bitmap); - mask = QBitmap::fromData(QSize(ZOOM_WIDTH, ZOOM_HEIGHT), zoom_mask_bitmap); - zoomCursor = QCursor(cursor, mask, ZOOM_HOT_X, ZOOM_HOT_Y); - - cursor = QBitmap::fromData(QSize(PAN_WIDTH, PAN_HEIGHT), pan_bitmap); - mask = QBitmap::fromData(QSize(PAN_WIDTH, PAN_HEIGHT), pan_mask_bitmap); - panCursor = QCursor(cursor, mask, PAN_HOT_X, PAN_HOT_Y); -} - -View3DInventorViewer::~View3DInventorViewer() -{ - // cleanup - this->backgroundroot->unref(); - this->backgroundroot = 0; - this->foregroundroot->unref(); - this->foregroundroot = 0; - this->pcBackGround->unref(); - this->pcBackGround = 0; - - setSceneGraph(0); - this->pEventCallback->unref(); - this->pEventCallback = 0; - this->pcViewProviderRoot->unref(); - this->pcViewProviderRoot = 0; - this->backlight->unref(); - this->backlight = 0; - - delete this->navigation; - - // Note: When closing the application the main window doesn't exist any more. - if (getMainWindow()) - getMainWindow()->setPaneText(2, QLatin1String("")); - - Gui::Selection().Detach(this); - - removeEventFilter(viewerEventFilter); - delete viewerEventFilter; - - if (_viewerPy) { - static_cast(_viewerPy)->_viewer = 0; - Py_DECREF(_viewerPy); - } -} - -void View3DInventorViewer::setDocument(Gui::Document* pcDocument) -{ - // write the document the viewer belongs to to the selection node - selectionRoot->pcDocument = pcDocument; -} - -void View3DInventorViewer::initialize() -{ - navigation = new CADNavigationStyle(); - navigation->setViewer(this); - - this->axiscrossEnabled = true; - this->axiscrossSize = 10; -} - -/// @cond DOXERR -void View3DInventorViewer::OnChange(Gui::SelectionSingleton::SubjectType& rCaller, - Gui::SelectionSingleton::MessageType Reason) -{ - if (Reason.Type == SelectionChanges::AddSelection || - Reason.Type == SelectionChanges::RmvSelection || - Reason.Type == SelectionChanges::SetSelection || - Reason.Type == SelectionChanges::ClrSelection) { - SoFCSelectionAction cAct(Reason); - cAct.apply(pcViewProviderRoot); - } -} -/// @endcond - -SbBool View3DInventorViewer::hasViewProvider(ViewProvider* pcProvider) const -{ - return _ViewProviderSet.find(pcProvider) != _ViewProviderSet.end(); -} - -/// adds an ViewProvider to the view, e.g. from a feature -void View3DInventorViewer::addViewProvider(ViewProvider* pcProvider) -{ - SoSeparator* root = pcProvider->getRoot(); - - if (root) { - pcViewProviderRoot->addChild(root); - _ViewProviderMap[root] = pcProvider; - } - - SoSeparator* fore = pcProvider->getFrontRoot(); - - if (fore) - foregroundroot->addChild(fore); - - SoSeparator* back = pcProvider->getBackRoot(); - - if (back) - backgroundroot->addChild(back); - - pcProvider->setOverrideMode(this->getOverrideMode()); - _ViewProviderSet.insert(pcProvider); -} - -void View3DInventorViewer::removeViewProvider(ViewProvider* pcProvider) -{ - if (this->editViewProvider == pcProvider) - resetEditingViewProvider(); - - SoSeparator* root = pcProvider->getRoot(); - - if (root) { - pcViewProviderRoot->removeChild(root); - _ViewProviderMap.erase(root); - } - - SoSeparator* fore = pcProvider->getFrontRoot(); - - if (fore) - foregroundroot->removeChild(fore); - - SoSeparator* back = pcProvider->getBackRoot(); - - if (back) - backgroundroot->removeChild(back); - - _ViewProviderSet.erase(pcProvider); -} - - -SbBool View3DInventorViewer::setEditingViewProvider(Gui::ViewProvider* p, int ModNum) -{ - if (this->editViewProvider) - return false; // only one view provider is editable at a time - - bool ok = p->startEditing(ModNum); - - if (ok) { - this->editViewProvider = p; - this->editViewProvider->setEditViewer(this, ModNum); - addEventCallback(SoEvent::getClassTypeId(), Gui::ViewProvider::eventCallback,this->editViewProvider); - } - - return ok; -} - -/// reset from edit mode -void View3DInventorViewer::resetEditingViewProvider() -{ - if (this->editViewProvider) { - this->editViewProvider->unsetEditViewer(this); - removeEventCallback(SoEvent::getClassTypeId(), Gui::ViewProvider::eventCallback,this->editViewProvider); - this->editViewProvider = 0; - } -} - -/// reset from edit mode -SbBool View3DInventorViewer::isEditingViewProvider() const -{ - return this->editViewProvider ? true : false; -} - -/// display override mode -void View3DInventorViewer::setOverrideMode(const std::string& mode) -{ - if (mode == overrideMode) - return; - - overrideMode = mode; - - for (std::set::iterator it = _ViewProviderSet.begin(); it != _ViewProviderSet.end(); ++it) - (*it)->setOverrideMode(mode); -} - -/// update override mode. doesn't affect providers -void View3DInventorViewer::updateOverrideMode(const std::string& mode) -{ - if (mode == overrideMode) - return; - - overrideMode = mode; -} - -void View3DInventorViewer::setViewportCB(void* userdata, SoAction* action) -{ - // Make sure to override the value set inside SoOffscreenRenderer::render() - if (action->isOfType(SoGLRenderAction::getClassTypeId())) { - SoFCOffscreenRenderer& renderer = SoFCOffscreenRenderer::instance(); - const SbViewportRegion& vp = renderer.getViewportRegion(); - SoViewportRegionElement::set(action->getState(), vp); - static_cast(action)->setViewportRegion(vp); - } -} - -void View3DInventorViewer::clearBufferCB(void* userdata, SoAction* action) -{ - if (action->isOfType(SoGLRenderAction::getClassTypeId())) { - // do stuff specific for GL rendering here. - glClear(GL_DEPTH_BUFFER_BIT); - } -} - -void View3DInventorViewer::setGLWidgetCB(void* userdata, SoAction* action) -{ - //FIXME: This causes the Coin error message: - // Coin error in SoNode::GLRenderS(): GL error: 'GL_STACK_UNDERFLOW', nodetype: - // Separator (set envvar COIN_GLERROR_DEBUGGING=1 and re-run to get more information) - if (action->isOfType(SoGLRenderAction::getClassTypeId())) { - QWidget* gl = reinterpret_cast(userdata); - SoGLWidgetElement::set(action->getState(), qobject_cast(gl)); - } -} - -void View3DInventorViewer::handleEventCB(void* ud, SoEventCallback* n) -{ - View3DInventorViewer* that = reinterpret_cast(ud); - SoGLRenderAction* glra = that->getSoRenderManager()->getGLRenderAction(); - SoAction* action = n->getAction(); - SoGLRenderActionElement::set(action->getState(), glra); - SoGLWidgetElement::set(action->getState(), qobject_cast(that->getGLWidget())); -} - -void View3DInventorViewer::setGradientBackground(bool on) -{ - if (on && backgroundroot->findChild(pcBackGround) == -1) - backgroundroot->addChild(pcBackGround); - else if(!on && backgroundroot->findChild(pcBackGround) != -1) - backgroundroot->removeChild(pcBackGround); -} - -bool View3DInventorViewer::hasGradientBackground() const -{ - return (backgroundroot->findChild(pcBackGround) != -1); -} - -void View3DInventorViewer::setGradientBackgroundColor(const SbColor& fromColor, - const SbColor& toColor) -{ - pcBackGround->setColorGradient(fromColor, toColor); -} - -void View3DInventorViewer::setGradientBackgroundColor(const SbColor& fromColor, - const SbColor& toColor, - const SbColor& midColor) -{ - pcBackGround->setColorGradient(fromColor, toColor, midColor); -} - -void View3DInventorViewer::setEnabledFPSCounter(bool on) -{ - fpsEnabled = on; -} - -void View3DInventorViewer::setAxisCross(bool on) -{ - SoNode* scene = getSceneGraph(); - SoSeparator* sep = static_cast(scene); - - if (on) { - if (!axisGroup) { - axisCross = new Gui::SoShapeScale; - Gui::SoAxisCrossKit* axisKit = new Gui::SoAxisCrossKit(); - axisKit->set("xAxis.appearance.drawStyle", "lineWidth 2"); - axisKit->set("yAxis.appearance.drawStyle", "lineWidth 2"); - axisKit->set("zAxis.appearance.drawStyle", "lineWidth 2"); - axisCross->setPart("shape", axisKit); - axisCross->scaleFactor = 1.0f; - axisGroup = new SoSkipBoundingGroup; - axisGroup->addChild(axisCross); - - sep->addChild(axisGroup); - } - } - else { - if (axisGroup) { - sep->removeChild(axisGroup); - axisGroup = 0; - } - } -} - -bool View3DInventorViewer::hasAxisCross(void) -{ - return axisGroup; -} - -void View3DInventorViewer::setNavigationType(Base::Type t) -{ - if (t.isBad()) - return; - - if (this->navigation && this->navigation->getTypeId() == t) - return; // nothing to do - - Base::BaseClass* base = static_cast(t.createInstance()); - - if (!base) - return; - - if (!base->getTypeId().isDerivedFrom(NavigationStyle::getClassTypeId())) { - delete base; - return; - } - - NavigationStyle* ns = static_cast(base); - ns->operator = (*this->navigation); - delete this->navigation; - this->navigation = ns; - this->navigation->setViewer(this); -} - -NavigationStyle* View3DInventorViewer::navigationStyle() const -{ - return this->navigation; -} - -SoDirectionalLight* View3DInventorViewer::getBacklight(void) const -{ - return this->backlight; -} - -void View3DInventorViewer::setBacklight(SbBool on) -{ - this->backlight->on = on; -} - -SbBool View3DInventorViewer::isBacklight(void) const -{ - return this->backlight->on.getValue(); -} - -void View3DInventorViewer::setSceneGraph(SoNode* root) -{ - inherited::setSceneGraph(root); - - SoSearchAction sa; - sa.setNode(this->backlight); - //we want the rendered scene with all lights and cameras, viewer->getSceneGraph would return - //the geometry scene only - SoNode* scene = this->getSoRenderManager()->getSceneGraph(); - if (scene && scene->getTypeId().isDerivedFrom(SoSeparator::getClassTypeId())) { - sa.apply(scene); - if (!sa.getPath()) - static_cast(scene)->insertChild(this->backlight, 0); - } -} - -void View3DInventorViewer::savePicture(int w, int h, const QColor& bg, QImage& img) const -{ - // If 'QGLPixelBuffer::hasOpenGLPbuffers()' returns false then - // SoQtOffscreenRenderer won't work. In this case we try to use - // Coin's implementation of the off-screen rendering. - bool useCoinOffscreenRenderer = !QGLPixelBuffer::hasOpenGLPbuffers(); - useCoinOffscreenRenderer = App::GetApplication().GetParameterGroupByPath - ("User parameter:BaseApp/Preferences/Document")-> - GetBool("CoinOffscreenRenderer", useCoinOffscreenRenderer); - - // if no valid color use the current background - bool useBackground = false; - SbViewportRegion vp(getSoRenderManager()->getViewportRegion()); - - if (w>0 && h>0) - vp.setWindowSize((short)w, (short)h); - - //NOTE: To support pixels per inch we must use SbViewportRegion::setPixelsPerInch( ppi ); - //The default value is 72.0. - //If we need to support grayscale images with must either use SoOffscreenRenderer::LUMINANCE or - //SoOffscreenRenderer::LUMINANCE_TRANSPARENCY. - - SoCallback* cb = 0; - - // for an invalid color use the viewer's current background color - QColor bgColor; - if (!bg.isValid()) { - if (backgroundroot->findChild(pcBackGround) == -1) { - bgColor = this->backgroundColor(); - } - else { - useBackground = true; - cb = new SoCallback; - cb->setCallback(clearBufferCB); - } - } - else { - bgColor = bg; - } - - SoSeparator* root = new SoSeparator; - root->ref(); - -#if (COIN_MAJOR_VERSION >= 4) - // The behaviour in Coin4 has changed so that when using the same instance of 'SoFCOffscreenRenderer' - // multiple times internally the biggest viewport size is stored and set to the SoGLRenderAction. - // The trick is to add a callback node and override the viewport size with what we want. - if (useCoinOffscreenRenderer) { - SoCallback* cbvp = new SoCallback; - cbvp->setCallback(setViewportCB); - root->addChild(cbvp); - } -#endif - - SoCamera* camera = getSoRenderManager()->getCamera(); - - if (useBackground) { - root->addChild(backgroundroot); - root->addChild(cb); - } - - root->addChild(getHeadlight()); - root->addChild(camera); - SoCallback* gl = new SoCallback; - gl->setCallback(setGLWidgetCB, this->getGLWidget()); - root->addChild(gl); - root->addChild(pcViewProviderRoot); - - if (useBackground) - root->addChild(cb); - - root->addChild(foregroundroot); - - try { - // render the scene - if (!useCoinOffscreenRenderer) { - SoQtOffscreenRenderer renderer(vp); - renderer.setNumPasses(4); - if (bgColor.isValid()) - renderer.setBackgroundColor(SbColor(bgColor.redF(), bgColor.greenF(), bgColor.blueF())); - if (!renderer.render(root)) - throw Base::Exception("Offscreen rendering failed"); - - renderer.writeToImage(img); - root->unref(); - } - else { - SoFCOffscreenRenderer& renderer = SoFCOffscreenRenderer::instance(); - renderer.setViewportRegion(vp); - if (bgColor.isValid()) - renderer.setBackgroundColor(SbColor(bgColor.redF(), bgColor.greenF(), bgColor.blueF())); - if (!renderer.render(root)) - throw Base::Exception("Offscreen rendering failed"); - - renderer.writeToImage(img); - root->unref(); - } - } - catch (...) { - root->unref(); - throw; // re-throw exception - } -} - -void View3DInventorViewer::saveGraphic(int pagesize, const QColor& bgcolor, SoVectorizeAction* va) const -{ - if (bgcolor.isValid()) - va->setBackgroundColor(true, SbColor(bgcolor.redF(), bgcolor.greenF(), bgcolor.blueF())); - - float border = 10.0f; - SbVec2s vpsize = this->getSoRenderManager()->getViewportRegion().getViewportSizePixels(); - float vpratio = ((float)vpsize[0]) / ((float)vpsize[1]); - - if (vpratio > 1.0f) { - va->setOrientation(SoVectorizeAction::LANDSCAPE); - vpratio = 1.0f / vpratio; - } - else { - va->setOrientation(SoVectorizeAction::PORTRAIT); - } - - va->beginStandardPage(SoVectorizeAction::PageSize(pagesize), border); - - // try to fill as much "paper" as possible - SbVec2f size = va->getPageSize(); - - float pageratio = size[0] / size[1]; - float xsize, ysize; - - if (pageratio < vpratio) { - xsize = size[0]; - ysize = xsize / vpratio; - } - else { - ysize = size[1]; - xsize = ysize * vpratio; - } - - float offx = border + (size[0]-xsize) * 0.5f; - float offy = border + (size[1]-ysize) * 0.5f; - - va->beginViewport(SbVec2f(offx, offy), SbVec2f(xsize, ysize)); - va->calibrate(this->getSoRenderManager()->getViewportRegion()); - - va->apply(this->getSoRenderManager()->getSceneGraph()); - - va->endViewport(); - va->endPage(); -} - -void View3DInventorViewer::startSelection(View3DInventorViewer::SelectionMode mode) -{ - navigation->startSelection(NavigationStyle::SelectionMode(mode)); -} - -void View3DInventorViewer::stopSelection() -{ - navigation->stopSelection(); -} - -bool View3DInventorViewer::isSelecting() const -{ - return navigation->isSelecting(); -} - -const std::vector& View3DInventorViewer::getPolygon(SbBool* clip_inner) const -{ - return navigation->getPolygon(clip_inner); -} - -SbVec2f View3DInventorViewer::screenCoordsOfPath(SoPath* path) const -{ - // Generate a matrix (well, a SoGetMatrixAction) that - // moves us to the picked object's coordinate space. - SoGetMatrixAction gma(getSoRenderManager()->getViewportRegion()); - gma.apply(path); - - // Use that matrix to translate the origin in the picked - // object's coordinate space into object space - SbVec3f imageCoords(0, 0, 0); - SbMatrix m = gma.getMatrix().transpose(); - m.multMatrixVec(imageCoords, imageCoords); - - // Now, project the object space coordinates of the object - // into "normalized" screen coordinates. - SbViewVolume vol = getSoRenderManager()->getCamera()->getViewVolume(); - vol.projectToScreen(imageCoords, imageCoords); - - // Translate "normalized" screen coordinates to pixel coords. - // - // Note: for some reason, projectToScreen() doesn't seem to - // handle non-square viewports properly. The X and Y are - // scaled such that [0,1] fits within the smaller of the window - // width or height. For instance, in a window that's 400px - // tall and 800px wide, the Y will be within [0,1], but X can - // vary within [-0.5,1.5]... - int width = getGLWidget()->width(), - height = getGLWidget()->height(); - - if (width >= height) { - // "Landscape" orientation, to square - imageCoords[0] *= height; - imageCoords[0] += (width-height) / 2.0; - imageCoords[1] *= height; - - } - else { - // "Portrait" orientation - imageCoords[0] *= width; - imageCoords[1] *= width; - imageCoords[1] += (height-width) / 2.0; - } - - return SbVec2f(imageCoords[0], imageCoords[1]); -} - -std::vector View3DInventorViewer::getGLPolygon(const std::vector& pnts) const -{ - const SbViewportRegion& vp = this->getSoRenderManager()->getViewportRegion(); - const SbVec2s& sz = vp.getWindowSize(); - short w,h; - sz.getValue(w,h); - const SbVec2s& sp = vp.getViewportSizePixels(); - const SbVec2s& op = vp.getViewportOriginPixels(); - const SbVec2f& siz = vp.getViewportSize(); - float dX, dY; - siz.getValue(dX, dY); - float fRatio = vp.getViewportAspectRatio(); - - std::vector poly; - - for (std::vector::const_iterator it = pnts.begin(); it != pnts.end(); ++it) { - SbVec2s loc = *it - op; - SbVec2f pos((float)loc[0]/(float)sp[0], (float)loc[1]/(float)sp[1]); - float pX,pY; - pos.getValue(pX,pY); - - // now calculate the real points respecting aspect ratio information - // - if (fRatio > 1.0f) { - pX = (pX - 0.5f*dX) * fRatio + 0.5f*dX; - pos.setValue(pX,pY); - } - else if(fRatio < 1.0f) { - pY = (pY - 0.5f*dY) / fRatio + 0.5f*dY; - pos.setValue(pX,pY); - } - - poly.push_back(pos); - } - - return poly; -} - -std::vector View3DInventorViewer::getGLPolygon(SbBool* clip_inner) const -{ - const std::vector& pnts = navigation->getPolygon(clip_inner); - return getGLPolygon(pnts); -} - -bool View3DInventorViewer::dumpToFile(SoNode* node, const char* filename, bool binary) const -{ - bool ret = false; - Base::FileInfo fi(filename); - - if (fi.hasExtension("idtf") || fi.hasExtension("svg")) { - int ps=4; - QColor c = Qt::white; - std::auto_ptr vo; - - if (fi.hasExtension("svg")) { - vo = std::auto_ptr(new SoFCVectorizeSVGAction()); - } - else if(fi.hasExtension("idtf")) { - vo = std::auto_ptr(new SoFCVectorizeU3DAction()); - } - else { - throw Base::Exception("Not supported vector graphic"); - } - - SoVectorOutput* out = vo->getOutput(); - - if (!out || !out->openFile(filename)) { - std::ostringstream a_out; - a_out << "Cannot open file '" << filename << "'"; - throw Base::Exception(a_out.str()); - } - - saveGraphic(ps,c,vo.get()); - out->closeFile(); - } - else { - // Try VRML and Inventor format - ret = SoFCDB::writeToFile(node, filename, binary); - } - - return ret; -} - -/** - * Sets the SoFCInteractiveElement to \a true. - */ -void View3DInventorViewer::interactionStartCB(void* data, SoQTQuarterAdaptor* viewer) -{ - SoGLRenderAction* glra = viewer->getSoRenderManager()->getGLRenderAction(); - SoFCInteractiveElement::set(glra->getState(), viewer->getSceneGraph(), true); -} - -/** - * Sets the SoFCInteractiveElement to \a false and forces a redraw. - */ -void View3DInventorViewer::interactionFinishCB(void* data, SoQTQuarterAdaptor* viewer) -{ - SoGLRenderAction* glra = viewer->getSoRenderManager()->getGLRenderAction(); - SoFCInteractiveElement::set(glra->getState(), viewer->getSceneGraph(), false); - viewer->redraw(); -} - -/** - * Logs the type of the action that traverses the Inventor tree. - */ -void View3DInventorViewer::interactionLoggerCB(void* ud, SoAction* action) -{ - Base::Console().Log("%s\n", action->getTypeId().getName().getString()); -} - -void View3DInventorViewer::addGraphicsItem(GLGraphicsItem* item) -{ - this->graphicsItems.push_back(item); -} - -void View3DInventorViewer::removeGraphicsItem(GLGraphicsItem* item) -{ - this->graphicsItems.remove(item); -} - -std::list View3DInventorViewer::getGraphicsItems() const -{ - return graphicsItems; -} - -std::list View3DInventorViewer::getGraphicsItemsOfType(const Base::Type& type) const -{ - std::list items; - - for(std::list::const_iterator it = this->graphicsItems.begin(); it != this->graphicsItems.end(); ++it) { - if((*it)->isDerivedFrom(type)) - items.push_back(*it); - } - - return items; -} - -void View3DInventorViewer::clearGraphicsItems() -{ - this->graphicsItems.clear(); -} - -void View3DInventorViewer::setRenderType(const RenderType type) -{ - renderType = type; - - glImage = QImage(); - if (type != Framebuffer) { - delete framebuffer; - framebuffer = 0; - } - - switch (type) { - case Native: - break; - case Framebuffer: - if (!framebuffer) { - const SbViewportRegion vp = this->getSoRenderManager()->getViewportRegion(); - SbVec2s size = vp.getViewportSizePixels(); - - QGLWidget* gl = static_cast(this->viewport()); - gl->makeCurrent(); - framebuffer = new QGLFramebufferObject(size[0],size[1],QGLFramebufferObject::Depth); - renderToFramebuffer(framebuffer); - } - break; - case Image: - { - QGLWidget* gl = static_cast(this->viewport()); - gl->makeCurrent(); - int w = gl->width(); - int h = gl->height(); - QImage img(QSize(w,h), QImage::Format_RGB32); - glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, img.bits()); - glImage = img; - } - break; - } -} - -void View3DInventorViewer::renderToFramebuffer(QGLFramebufferObject* fbo) -{ - static_cast(this->viewport())->makeCurrent(); - fbo->bind(); - int width = fbo->size().width(); - int height = fbo->size().height(); - - glDisable(GL_TEXTURE_2D); - glEnable(GL_LIGHTING); - glEnable(GL_DEPTH_TEST); - glEnable(GL_LINE_SMOOTH); - - const QColor col = this->backgroundColor(); - glViewport(0, 0, width, height); - glClearColor(col.redF(), col.greenF(), col.blueF(), 1.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glDepthRange(0.1,1.0); - - SoGLRenderAction gl(SbViewportRegion(width, height)); - // When creating a new GL render action we have to copy over the cache context id - // For further details see init(). - uint32_t id = this->getSoRenderManager()->getGLRenderAction()->getCacheContext(); - gl.setCacheContext(id); - gl.setTransparencyType(SoGLRenderAction::SORTED_OBJECT_SORTED_TRIANGLE_BLEND); - gl.apply(this->backgroundroot); - gl.apply(this->getSoRenderManager()->getSceneGraph()); - gl.apply(this->foregroundroot); - - if (this->axiscrossEnabled) { - this->drawAxisCross(); - } - - fbo->release(); -} - -void View3DInventorViewer::actualRedraw() -{ - switch (renderType) { - case Native: - renderScene(); - break; - case Framebuffer: - renderFramebuffer(); - break; - case Image: - renderGLImage(); - break; - } -} - -void View3DInventorViewer::renderFramebuffer() -{ - const SbViewportRegion vp = this->getSoRenderManager()->getViewportRegion(); - SbVec2s size = vp.getViewportSizePixels(); - - glDisable(GL_LIGHTING); - glViewport(0, 0, size[0], size[1]); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - glDisable(GL_DEPTH_TEST); - - glClear(GL_COLOR_BUFFER_BIT); - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, this->framebuffer->texture()); - glColor3f(1.0, 1.0, 1.0); - - glBegin(GL_QUADS); - glTexCoord2f(0.0f, 0.0f); - glVertex2f(-1.0, -1.0f); - glTexCoord2f(1.0f, 0.0f); - glVertex2f(1.0f, -1.0f); - glTexCoord2f(1.0f, 1.0f); - glVertex2f(1.0f, 1.0f); - glTexCoord2f(0.0f, 1.0f); - glVertex2f(-1.0f, 1.0f); - glEnd(); - - printDimension(); - navigation->redraw(); - - for (std::list::iterator it = this->graphicsItems.begin(); it != this->graphicsItems.end(); ++it) - (*it)->paintGL(); - - glEnable(GL_LIGHTING); - glEnable(GL_DEPTH_TEST); -} - -void View3DInventorViewer::renderGLImage() -{ - const SbViewportRegion vp = this->getSoRenderManager()->getViewportRegion(); - SbVec2s size = vp.getViewportSizePixels(); - - glDisable(GL_LIGHTING); - glViewport(0, 0, size[0], size[1]); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(0, size[0], 0, size[1], 0, 100); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - - glDisable(GL_DEPTH_TEST); - glClear(GL_COLOR_BUFFER_BIT); - - glRasterPos2f(0,0); - glDrawPixels(glImage.width(),glImage.height(),GL_RGBA,GL_UNSIGNED_BYTE,glImage.bits()); - - printDimension(); - navigation->redraw(); - - for (std::list::iterator it = this->graphicsItems.begin(); it != this->graphicsItems.end(); ++it) - (*it)->paintGL(); - - glEnable(GL_LIGHTING); - glEnable(GL_DEPTH_TEST); -} - -//#define ENABLE_GL_DEPTH_RANGE -// The calls of glDepthRange inside renderScene() causes problems with transparent objects -// so that's why it is disabled now: http://forum.freecadweb.org/viewtopic.php?f=3&t=6037&hilit=transparency - -// Documented in superclass. Overrides this method to be able to draw -// the axis cross, if selected, and to keep a continuous animation -// upon spin. -void View3DInventorViewer::renderScene(void) -{ - // Must set up the OpenGL viewport manually, as upon resize - // operations, Coin won't set it up until the SoGLRenderAction is - // applied again. And since we need to do glClear() before applying - // the action.. - const SbViewportRegion vp = this->getSoRenderManager()->getViewportRegion(); - SbVec2s origin = vp.getViewportOriginPixels(); - SbVec2s size = vp.getViewportSizePixels(); - glViewport(origin[0], origin[1], size[0], size[1]); - - const QColor col = this->backgroundColor(); - glClearColor(col.redF(), col.greenF(), col.blueF(), 0.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glEnable(GL_DEPTH_TEST); - -#if defined(ENABLE_GL_DEPTH_RANGE) - // using 90% of the z-buffer for the background and the main node - glDepthRange(0.1,1.0); -#endif - - // Render our scenegraph with the image. - SoGLRenderAction* glra = this->getSoRenderManager()->getGLRenderAction(); - SoGLWidgetElement::set(glra->getState(), qobject_cast(this->getGLWidget())); - SoGLRenderActionElement::set(glra->getState(), glra); - glra->apply(this->backgroundroot); - - navigation->updateAnimation(); - - try { - // Render normal scenegraph. - inherited::actualRedraw(); - } - catch(const Base::MemoryException&) { - // FIXME: If this exception appears then the background and camera position get broken somehow. (Werner 2006-02-01) - for (std::set::iterator it = _ViewProviderSet.begin(); it != _ViewProviderSet.end(); ++it) - (*it)->hide(); - - inherited::actualRedraw(); - QMessageBox::warning(parentWidget(), QObject::tr("Out of memory"), - QObject::tr("Not enough memory available to display the data.")); - } - -#if defined (ENABLE_GL_DEPTH_RANGE) - // using 10% of the z-buffer for the foreground node - glDepthRange(0.0,0.1); -#endif - - // Render overlay front scenegraph. - glra->apply(this->foregroundroot); - - if (this->axiscrossEnabled) { - this->drawAxisCross(); - } - -#if defined (ENABLE_GL_DEPTH_RANGE) - // using the main portion of z-buffer again (for frontbuffer highlighting) - glDepthRange(0.1,1.0); -#endif - - // Immediately reschedule to get continous spin animation. - if (this->isAnimating()) { - this->getSoRenderManager()->scheduleRedraw(); - } - -#if 0 // this breaks highlighting of edges - glDisable(GL_LIGHTING); - glDisable(GL_DEPTH_TEST); -#endif - - printDimension(); - navigation->redraw(); - - for (std::list::iterator it = this->graphicsItems.begin(); it != this->graphicsItems.end(); ++it) - (*it)->paintGL(); - - //fps rendering - if (fpsEnabled) { - std::stringstream stream; - stream.precision(1); - stream.setf(std::ios::fixed | std::ios::showpoint); - stream << renderTime << " ms / " << 1000./renderTime << " fps"; - draw2DString(stream.str().c_str(), SbVec2s(10,10), SbVec2f(0.1f,0.1f)); - } - -#if 0 // this breaks highlighting of edges - glEnable(GL_LIGHTING); - glEnable(GL_DEPTH_TEST); -#endif -} - -void View3DInventorViewer::setSeekMode(SbBool on) -{ - // Overrides this method to make sure any animations are stopped - // before we go into seek mode. - - // Note: this method is almost identical to the setSeekMode() in the - // SoQtFlyViewer and SoQtPlaneViewer, so migrate any changes. - - if (this->isAnimating()) { - this->stopAnimating(); - } - - inherited::setSeekMode(on); - navigation->setViewingMode(on ? NavigationStyle::SEEK_WAIT_MODE : - (this->isViewing() ? - NavigationStyle::IDLE : NavigationStyle::INTERACT)); -} - -void View3DInventorViewer::printDimension() -{ - SoCamera* cam = getSoRenderManager()->getCamera(); - - if (!cam) return; // no camera there - - SoType t = getSoRenderManager()->getCamera()->getTypeId(); - - if (t.isDerivedFrom(SoOrthographicCamera::getClassTypeId())) { - const SbViewportRegion& vp = getSoRenderManager()->getViewportRegion(); - const SbVec2s& size = vp.getWindowSize(); - short dimX, dimY; - size.getValue(dimX, dimY); - - float fHeight = static_cast(getSoRenderManager()->getCamera())->height.getValue(); - float fWidth = fHeight; - - if (dimX > dimY) - fWidth *= ((float)dimX)/((float)dimY); - else if(dimX < dimY) - fHeight *= ((float)dimY)/((float)dimX); - - float fLog = float(log10(fWidth)), fFac; - int nExp = int(fLog); - QString unit; - - if (nExp >= 6) { - fFac = 1.0e+6f; - unit = QLatin1String("km"); - } - else if (nExp >= 3) { - fFac = 1.0e+3f; - unit = QLatin1String("m"); - } - else if ((nExp >= 0) && (fLog > 0.0f)) { - fFac = 1.0e+0f; - unit = QLatin1String("mm"); - } - else if (nExp >= -3) { - fFac = 1.0e-3f; - unit = QLatin1String("um"); - } - else { - fFac = 1.0e-6f; - unit = QLatin1String("nm"); - } - - QString dim = QString::fromLatin1("%1 x %2 %3") - .arg(fWidth / fFac,0,'f',2) - .arg(fHeight / fFac,0,'f',2) - .arg(unit); - getMainWindow()->setPaneText(2, dim); - } - else - getMainWindow()->setPaneText(2, QLatin1String("")); -} - -void View3DInventorViewer::selectAll() -{ - std::vector objs; - - for (std::set::iterator it = _ViewProviderSet.begin(); it != _ViewProviderSet.end(); ++it) { - if ((*it)->getTypeId().isDerivedFrom(ViewProviderDocumentObject::getClassTypeId())) { - ViewProviderDocumentObject* vp = static_cast(*it); - App::DocumentObject* obj = vp->getObject(); - - if (obj) objs.push_back(obj); - } - } - - if (!objs.empty()) - Gui::Selection().setSelection(objs.front()->getDocument()->getName(), objs); -} - - -bool View3DInventorViewer::processSoEvent(const SoEvent* ev) -{ - if (isRedirectedToSceneGraph()) { - SbBool processed = inherited::processSoEvent(ev); - - if(!processed) - processed = navigation->processEvent(ev); - - return processed; - } - - if (ev->getTypeId().isDerivedFrom(SoKeyboardEvent::getClassTypeId())) { - // filter out 'Q' and 'ESC' keys - const SoKeyboardEvent* const ke = static_cast(ev); - - switch(ke->getKey()) { - case SoKeyboardEvent::ESCAPE: - case SoKeyboardEvent::Q: // ignore 'Q' keys (to prevent app from being closed) - return inherited::processSoEvent(ev); - - default: - break; - } - } - - return navigation->processEvent(ev); -} - -SbBool View3DInventorViewer::processSoEventBase(const SoEvent* const ev) -{ - return inherited::processSoEvent(ev); -} - -SbVec3f View3DInventorViewer::getViewDirection() const -{ - SoCamera* cam = this->getSoRenderManager()->getCamera(); - - if (!cam) return SbVec3f(0,0,-1); // this is the default - - SbRotation camrot = cam->orientation.getValue(); - SbVec3f lookat(0, 0, -1); // init to default view direction vector - camrot.multVec(lookat, lookat); - return lookat; -} - -void View3DInventorViewer::setViewDirection(SbVec3f dir) -{ - SoCamera* cam = this->getSoRenderManager()->getCamera(); - if (cam) - cam->orientation.setValue(SbRotation(SbVec3f(0, 0, -1), dir)); -} - - -SbVec3f View3DInventorViewer::getUpDirection() const -{ - SoCamera* cam = this->getSoRenderManager()->getCamera(); - - if (!cam) return SbVec3f(0,1,0); - - SbRotation camrot = cam->orientation.getValue(); - SbVec3f upvec(0, 1, 0); // init to default up vector - camrot.multVec(upvec, upvec); - return upvec; -} - -SbRotation View3DInventorViewer::getCameraOrientation() const -{ - SoCamera* cam = this->getSoRenderManager()->getCamera(); - - if (!cam) - return SbRotation(0,0,0,1); // this is the default - - return cam->orientation.getValue(); -} - -SbVec3f View3DInventorViewer::getPointOnScreen(const SbVec2s& pnt) const -{ - const SbViewportRegion& vp = this->getSoRenderManager()->getViewportRegion(); - - short x,y; - pnt.getValue(x,y); - SbVec2f siz = vp.getViewportSize(); - float dX, dY; - siz.getValue(dX, dY); - - float fRatio = vp.getViewportAspectRatio(); - float pX = (float)x / float(vp.getViewportSizePixels()[0]); - float pY = (float)y / float(vp.getViewportSizePixels()[1]); - - // now calculate the real points respecting aspect ratio information - // - if (fRatio > 1.0f) { - pX = (pX - 0.5f*dX) * fRatio + 0.5f*dX; - } - else if(fRatio < 1.0f) { - pY = (pY - 0.5f*dY) / fRatio + 0.5f*dY; - } - - SoCamera* pCam = this->getSoRenderManager()->getCamera(); - - if (!pCam) return SbVec3f(); // return invalid point - - SbViewVolume vol = pCam->getViewVolume(); - - float nearDist = pCam->nearDistance.getValue(); - float farDist = pCam->farDistance.getValue(); - float focalDist = pCam->focalDistance.getValue(); - - if (focalDist < nearDist || focalDist > farDist) - focalDist = 0.5f*(nearDist + farDist); - - SbLine line; - SbVec3f pt; - SbPlane focalPlane = vol.getPlane(focalDist); - vol.projectPointToLine(SbVec2f(pX,pY), line); - focalPlane.intersect(line, pt); - - return pt; -} - -void View3DInventorViewer::getNearPlane(SbVec3f& rcPt, SbVec3f& rcNormal) const -{ - SoCamera* pCam = getSoRenderManager()->getCamera(); - - if (!pCam) return; // just do nothing - - SbViewVolume vol = pCam->getViewVolume(); - - // get the normal of the front clipping plane - SbPlane nearPlane = vol.getPlane(vol.nearDist); - float d = nearPlane.getDistanceFromOrigin(); - rcNormal = nearPlane.getNormal(); - rcNormal.normalize(); - float nx, ny, nz; - rcNormal.getValue(nx, ny, nz); - rcPt.setValue(d*rcNormal[0], d*rcNormal[1], d*rcNormal[2]); -} - -void View3DInventorViewer::getFarPlane(SbVec3f& rcPt, SbVec3f& rcNormal) const -{ - SoCamera* pCam = getSoRenderManager()->getCamera(); - - if (!pCam) return; // just do nothing - - SbViewVolume vol = pCam->getViewVolume(); - - // get the normal of the back clipping plane - SbPlane farPlane = vol.getPlane(vol.nearDist+vol.nearToFar); - float d = farPlane.getDistanceFromOrigin(); - rcNormal = farPlane.getNormal(); - rcNormal.normalize(); - float nx, ny, nz; - rcNormal.getValue(nx, ny, nz); - rcPt.setValue(d*rcNormal[0], d*rcNormal[1], d*rcNormal[2]); -} - -SbVec3f View3DInventorViewer::projectOnNearPlane(const SbVec2f& pt) const -{ - SbVec3f pt1, pt2; - SoCamera* cam = this->getSoRenderManager()->getCamera(); - - if (!cam) return SbVec3f(); // return invalid point - - SbViewVolume vol = cam->getViewVolume(); - vol.projectPointToLine(pt, pt1, pt2); - return pt1; -} - -SbVec3f View3DInventorViewer::projectOnFarPlane(const SbVec2f& pt) const -{ - SbVec3f pt1, pt2; - SoCamera* cam = this->getSoRenderManager()->getCamera(); - - if (!cam) return SbVec3f(); // return invalid point - - SbViewVolume vol = cam->getViewVolume(); - vol.projectPointToLine(pt, pt1, pt2); - return pt2; -} - -void View3DInventorViewer::toggleClippingPlane() -{ - if (pcViewProviderRoot->getNumChildren() > 0 && - pcViewProviderRoot->getChild(0)->getTypeId() == - SoClipPlaneManip::getClassTypeId()) { - pcViewProviderRoot->removeChild(0); - } - else { - SoClipPlaneManip* clip = new SoClipPlaneManip; - SoGetBoundingBoxAction action(this->getSoRenderManager()->getViewportRegion()); - action.apply(this->getSoRenderManager()->getSceneGraph()); - SbBox3f box = action.getBoundingBox(); - - if (!box.isEmpty()) { - // adjust to overall bounding box of the scene - clip->setValue(box, SbVec3f(0.0f,0.0f,1.0f), 1.0f); - } - - pcViewProviderRoot->insertChild(clip,0); - } -} - -bool View3DInventorViewer::hasClippingPlane() const -{ - if (pcViewProviderRoot && pcViewProviderRoot->getNumChildren() > 0) { - return (pcViewProviderRoot->getChild(0)->getTypeId() - == SoClipPlaneManip::getClassTypeId()); - } - - return false; -} - -/** - * This method picks the closest point to the camera in the underlying scenegraph - * and returns its location and normal. - * If no point was picked false is returned. - */ -bool View3DInventorViewer::pickPoint(const SbVec2s& pos,SbVec3f& point,SbVec3f& norm) const -{ - // attempting raypick in the event_cb() callback method - SoRayPickAction rp(getSoRenderManager()->getViewportRegion()); - rp.setPoint(pos); - rp.apply(getSoRenderManager()->getSceneGraph()); - SoPickedPoint* Point = rp.getPickedPoint(); - - if (Point) { - point = Point->getObjectPoint(); - norm = Point->getObjectNormal(); - return true; - } - - return false; -} - -/** - * This method is provided for convenience and does basically the same as method - * above unless that it returns an SoPickedPoint object with additional information. - * \note It is in the response of the client programmer to delete the returned - * SoPickedPoint object. - */ -SoPickedPoint* View3DInventorViewer::pickPoint(const SbVec2s& pos) const -{ - SoRayPickAction rp(getSoRenderManager()->getViewportRegion()); - rp.setPoint(pos); - rp.apply(getSoRenderManager()->getSceneGraph()); - - // returns a copy of the point - SoPickedPoint* pick = rp.getPickedPoint(); - //return (pick ? pick->copy() : 0); // needs the same instance of CRT under MS Windows - return (pick ? new SoPickedPoint(*pick) : 0); -} - -const SoPickedPoint* View3DInventorViewer::getPickedPoint(SoEventCallback* n) const -{ - if (selectionRoot) - return selectionRoot->getPickedPoint(n->getAction()); - else - return n->getPickedPoint(); -} - -SbBool View3DInventorViewer::pubSeekToPoint(const SbVec2s& pos) -{ - return this->seekToPoint(pos); -} - -void View3DInventorViewer::pubSeekToPoint(const SbVec3f& pos) -{ - this->seekToPoint(pos); -} - -void View3DInventorViewer::setCameraOrientation(const SbRotation& rot, SbBool moveTocenter) -{ - navigation->setCameraOrientation(rot, moveTocenter); -} - -void View3DInventorViewer::setCameraType(SoType t) -{ - inherited::setCameraType(t); - - if (t.isDerivedFrom(SoPerspectiveCamera::getClassTypeId())) { - // When doing a viewAll() for an orthographic camera and switching - // to perspective the scene looks completely strange because of the - // heightAngle. Setting it to 45 deg also causes an issue with a too - // close camera but we don't have this other ugly effect. - SoCamera* cam = this->getSoRenderManager()->getCamera(); - - if(cam == 0) return; - - static_cast(cam)->heightAngle = (float)(M_PI / 4.0); - } -} - -void View3DInventorViewer::moveCameraTo(const SbRotation& rot, const SbVec3f& pos, int steps, int ms) -{ - SoCamera* cam = this->getSoRenderManager()->getCamera(); - - if (cam == 0) return; - - SbVec3f campos = cam->position.getValue(); - SbRotation camrot = cam->orientation.getValue(); - - QEventLoop loop; - QTimer timer; - timer.setSingleShot(true); - QObject::connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit())); - - for (int i=0; iorientation.setValue(currot); - cam->position.setValue(curpos); - timer.start(Base::clamp(ms,0,5000)); - loop.exec(QEventLoop::ExcludeUserInputEvents); - } - - cam->orientation.setValue(rot); - cam->position.setValue(pos); -} - -void View3DInventorViewer::animatedViewAll(int steps, int ms) -{ - SoCamera* cam = this->getSoRenderManager()->getCamera(); - - if (!cam) - return; - - SbVec3f campos = cam->position.getValue(); - SbRotation camrot = cam->orientation.getValue(); - SbViewportRegion vp = this->getSoRenderManager()->getViewportRegion(); - SoGetBoundingBoxAction action(vp); - action.apply(this->getSoRenderManager()->getSceneGraph()); - SbBox3f box = action.getBoundingBox(); - -#if (COIN_MAJOR_VERSION >= 3) - float aspectRatio = vp.getViewportAspectRatio(); -#endif - - if (box.isEmpty()) - return; - - SbSphere sphere; - sphere.circumscribe(box); - - SbVec3f direction, pos; - camrot.multVec(SbVec3f(0, 0, -1), direction); - - bool isOrthographic = false; - float height = 0; - float diff = 0; - - if (cam->isOfType(SoOrthographicCamera::getClassTypeId())) { - isOrthographic = true; - height = static_cast(cam)->height.getValue(); -#if (COIN_MAJOR_VERSION >= 3) - if (aspectRatio < 1.0f) - diff = sphere.getRadius() * 2 - height * aspectRatio; - else -#endif - diff = sphere.getRadius() * 2 - height; - pos = (box.getCenter() - direction * sphere.getRadius()); - } - else if (cam->isOfType(SoPerspectiveCamera::getClassTypeId())) { - float movelength = sphere.getRadius()/float(tan(static_cast - (cam)->heightAngle.getValue() / 2.0)); - pos = box.getCenter() - direction * movelength; - } - - QEventLoop loop; - QTimer timer; - timer.setSingleShot(true); - QObject::connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit())); - - for (int i=0; i(cam)->height.setValue(camHeight); - } - - SbVec3f curpos = campos * (1.0f-s) + pos * s; - cam->position.setValue(curpos); - timer.start(Base::clamp(ms,0,5000)); - loop.exec(QEventLoop::ExcludeUserInputEvents); - } -} - -#if BUILD_VR -extern View3DInventorRiftViewer* oculusStart(void); -extern bool oculusUp (void); -extern void oculusStop (void); -void oculusSetTestScene(View3DInventorRiftViewer *window); -#endif - -void View3DInventorViewer::viewVR(void) -{ -#if BUILD_VR -<<<<<<< b5cee108f51944ec0e4e42f663a543f235e65665 - if (oculusUp()) { - oculusStop(); - } - else { -======= - if(oculusUp()) - oculusStop(); - else{ ->>>>>>> make SoFCUnifiedSelection work with nested children in 3DView - View3DInventorRiftViewer* riftWin = oculusStart(); - riftWin->setSceneGraph(pcViewProviderRoot); - } -#endif -} - -void View3DInventorViewer::boxZoom(const SbBox2s& box) -{ - navigation->boxZoom(box); -} - -void View3DInventorViewer::viewAll() -{ - // in the scene graph we may have objects which we want to exlcude - // when doing a fit all. Such objects must be part of the group - // SoSkipBoundingGroup. - SoSearchAction sa; - sa.setType(SoSkipBoundingGroup::getClassTypeId()); - sa.setInterest(SoSearchAction::ALL); - sa.apply(this->getSoRenderManager()->getSceneGraph()); - const SoPathList& pathlist = sa.getPaths(); - - for (int i = 0; i < pathlist.getLength(); i++) { - SoPath* path = pathlist[i]; - SoSkipBoundingGroup* group = static_cast(path->getTail()); - group->mode = SoSkipBoundingGroup::EXCLUDE_BBOX; - } - - // Set the height angle to 45 deg - SoCamera* cam = this->getSoRenderManager()->getCamera(); - - if (cam && cam->getTypeId().isDerivedFrom(SoPerspectiveCamera::getClassTypeId())) - static_cast(cam)->heightAngle = (float)(M_PI / 4.0); - - if (isAnimationEnabled()) - animatedViewAll(10, 20); - - // make sure everything is visible - if (cam) - cam->viewAll(getSoRenderManager()->getSceneGraph(), this->getSoRenderManager()->getViewportRegion()); - - for (int i = 0; i < pathlist.getLength(); i++) { - SoPath* path = pathlist[i]; - SoSkipBoundingGroup* group = static_cast(path->getTail()); - group->mode = SoSkipBoundingGroup::INCLUDE_BBOX; - } -} - -void View3DInventorViewer::viewAll(float factor) -{ - SoCamera* cam = this->getSoRenderManager()->getCamera(); - - if (!cam) return; - - if (factor <= 0.0f) return; - - if (factor != 1.0f) { - SoSearchAction sa; - sa.setType(SoSkipBoundingGroup::getClassTypeId()); - sa.setInterest(SoSearchAction::ALL); - sa.apply(this->getSoRenderManager()->getSceneGraph()); - const SoPathList& pathlist = sa.getPaths(); - - for(int i = 0; i < pathlist.getLength(); i++) { - SoPath* path = pathlist[i]; - SoSkipBoundingGroup* group = static_cast(path->getTail()); - group->mode = SoSkipBoundingGroup::EXCLUDE_BBOX; - } - - SoGetBoundingBoxAction action(this->getSoRenderManager()->getViewportRegion()); - action.apply(this->getSoRenderManager()->getSceneGraph()); - SbBox3f box = action.getBoundingBox(); - float minx,miny,minz,maxx,maxy,maxz; - box.getBounds(minx,miny,minz,maxx,maxy,maxz); - - for (int i = 0; i < pathlist.getLength(); i++) { - SoPath* path = pathlist[i]; - SoSkipBoundingGroup* group = static_cast(path->getTail()); - group->mode = SoSkipBoundingGroup::INCLUDE_BBOX; - } - - SoCube* cube = new SoCube(); - cube->width = factor*(maxx-minx); - cube->height = factor*(maxy-miny); - cube->depth = factor*(maxz-minz); - - // fake a scenegraph with the desired bounding size - SoSeparator* graph = new SoSeparator(); - graph->ref(); - SoTranslation* tr = new SoTranslation(); - tr->translation.setValue(box.getCenter()); - - graph->addChild(tr); - graph->addChild(cube); - cam->viewAll(graph, this->getSoRenderManager()->getViewportRegion()); - graph->unref(); - } - else { - viewAll(); - } -} - -void View3DInventorViewer::viewSelection() -{ -#if 0 - // Search for all SoFCSelection nodes - SoSearchAction searchAction; - searchAction.setType(SoFCSelection::getClassTypeId()); - searchAction.setInterest(SoSearchAction::ALL); - searchAction.apply(pcViewProviderRoot); - - SoPathList& paths = searchAction.getPaths(); - int countPaths = paths.getLength(); - - SoGroup* root = new SoGroup(); - root->ref(); - - for(int i=0; igetTail(); - - if (!node || node->getTypeId() != SoFCSelection::getClassTypeId()) - continue; // should not happen - - SoFCSelection* select = static_cast(node); - - // Check only document and object name but not sub-element name - if (Selection().isSelected(select->documentName.getValue().getString(), - select->objectName.getValue().getString())) { - root->addChild(select); - } - } - -#else - SoGroup* root = new SoGroup(); - root->ref(); - - std::vector selection = Selection().getObjectsOfType(App::DocumentObject::getClassTypeId()); - - for (std::vector::iterator it = selection.begin(); it != selection.end(); ++it) { - ViewProvider* vp = Application::Instance->getViewProvider(*it); - - if (vp) { - root->addChild(vp->getRoot()); - } - } - -#endif - - SoCamera* cam = this->getSoRenderManager()->getCamera(); - if (cam) - cam->viewAll(root, this->getSoRenderManager()->getViewportRegion()); - - root->unref(); -} - -/*! - Decide if it should be possible to start a spin animation of the - model in the viewer by releasing the mouse button while dragging. - - If the \a enable flag is \c false and we're currently animating, the - spin will be stopped. -*/ -void -View3DInventorViewer::setAnimationEnabled(const SbBool enable) -{ - navigation->setAnimationEnabled(enable); -} - -/*! - Query whether or not it is possible to start a spinning animation by - releasing the left mouse button while dragging the mouse. -*/ - -SbBool -View3DInventorViewer::isAnimationEnabled(void) const -{ - return navigation->isAnimationEnabled(); -} - -/*! - Query if the model in the viewer is currently in spinning mode after - a user drag. -*/ -SbBool View3DInventorViewer::isAnimating(void) const -{ - return navigation->isAnimating(); -} - -/*! - * Starts programmatically the viewer in animation mode. The given axis direction - * is always in screen coordinates, not in world coordinates. - */ -void View3DInventorViewer::startAnimating(const SbVec3f& axis, float velocity) -{ - navigation->startAnimating(axis, velocity); -} - -void View3DInventorViewer::stopAnimating(void) -{ - navigation->stopAnimating(); -} - -void View3DInventorViewer::setPopupMenuEnabled(const SbBool on) -{ - navigation->setPopupMenuEnabled(on); -} - -SbBool View3DInventorViewer::isPopupMenuEnabled(void) const -{ - return navigation->isPopupMenuEnabled(); -} - -/*! - Set the flag deciding whether or not to show the axis cross. -*/ - -void -View3DInventorViewer::setFeedbackVisibility(const SbBool enable) -{ - if (enable == this->axiscrossEnabled) { - return; - } - - this->axiscrossEnabled = enable; - - if (this->isViewing()) { - this->getSoRenderManager()->scheduleRedraw(); - } -} - -/*! - Check if the feedback axis cross is visible. -*/ - -SbBool -View3DInventorViewer::isFeedbackVisible(void) const -{ - return this->axiscrossEnabled; -} - -/*! - Set the size of the feedback axiscross. The value is interpreted as - an approximate percentage chunk of the dimensions of the total - canvas. -*/ -void -View3DInventorViewer::setFeedbackSize(const int size) -{ - if (size < 1) { - return; - } - - this->axiscrossSize = size; - - if (this->isFeedbackVisible() && this->isViewing()) { - this->getSoRenderManager()->scheduleRedraw(); - } -} - -/*! - Return the size of the feedback axis cross. Default is 10. -*/ - -int -View3DInventorViewer::getFeedbackSize(void) const -{ - return this->axiscrossSize; -} - -/*! - Decide whether or not the mouse pointer cursor should be visible in - the rendering canvas. -*/ -void View3DInventorViewer::setCursorEnabled(SbBool enable) -{ - this->setCursorRepresentation(navigation->getViewingMode()); -} - -void View3DInventorViewer::afterRealizeHook(void) -{ - inherited::afterRealizeHook(); - this->setCursorRepresentation(navigation->getViewingMode()); -} - -// Documented in superclass. This method overridden from parent class -// to make sure the mouse pointer cursor is updated. -void View3DInventorViewer::setViewing(SbBool enable) -{ - - if (this->isViewing() == enable) { - return; - } - - navigation->setViewingMode(enable ? - NavigationStyle::IDLE : NavigationStyle::INTERACT); - inherited::setViewing(enable); -} - -//**************************************************************************** - -// Bitmap representations of an "X", a "Y" and a "Z" for the axis cross. -static GLubyte xbmp[] = { 0x11,0x11,0x0a,0x04,0x0a,0x11,0x11 }; -static GLubyte ybmp[] = { 0x04,0x04,0x04,0x04,0x0a,0x11,0x11 }; -static GLubyte zbmp[] = { 0x1f,0x10,0x08,0x04,0x02,0x01,0x1f }; - -void View3DInventorViewer::drawAxisCross(void) -{ - // FIXME: convert this to a superimposition scenegraph instead of - // OpenGL calls. 20020603 mortene. - - // Store GL state. - glPushAttrib(GL_ALL_ATTRIB_BITS); - GLfloat depthrange[2]; - glGetFloatv(GL_DEPTH_RANGE, depthrange); - GLdouble projectionmatrix[16]; - glGetDoublev(GL_PROJECTION_MATRIX, projectionmatrix); - - glDepthFunc(GL_ALWAYS); - glDepthMask(GL_TRUE); - glDepthRange(0, 0); - glEnable(GL_DEPTH_TEST); - glDisable(GL_LIGHTING); - glEnable(GL_COLOR_MATERIAL); - glDisable(GL_BLEND); // Kills transparency. - - // Set the viewport in the OpenGL canvas. Dimensions are calculated - // as a percentage of the total canvas size. - SbVec2s view = this->getSoRenderManager()->getSize(); - const int pixelarea = - int(float(this->axiscrossSize)/100.0f * std::min(view[0], view[1])); -#if 0 // middle of canvas - SbVec2s origin(view[0]/2 - pixelarea/2, view[1]/2 - pixelarea/2); -#endif // middle of canvas -#if 1 // lower right of canvas - SbVec2s origin(view[0] - pixelarea, 0); -#endif // lower right of canvas - glViewport(origin[0], origin[1], pixelarea, pixelarea); - - // Set up the projection matrix. - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - - const float NEARVAL = 0.1f; - const float FARVAL = 10.0f; - const float dim = NEARVAL * float(tan(M_PI / 8.0)); // FOV is 45? (45/360 = 1/8) - glFrustum(-dim, dim, -dim, dim, NEARVAL, FARVAL); - - - // Set up the model matrix. - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - SbMatrix mx; - SoCamera* cam = this->getSoRenderManager()->getCamera(); - - // If there is no camera (like for an empty scene, for instance), - // just use an identity rotation. - if (cam) { - mx = cam->orientation.getValue(); - } - else { - mx = SbMatrix::identity(); - } - - mx = mx.inverse(); - mx[3][2] = -3.5; // Translate away from the projection point (along z axis). - glLoadMatrixf((float*)mx); - - - // Find unit vector end points. - SbMatrix px; - glGetFloatv(GL_PROJECTION_MATRIX, (float*)px); - SbMatrix comb = mx.multRight(px); - - SbVec3f xpos; - comb.multVecMatrix(SbVec3f(1,0,0), xpos); - xpos[0] = (1 + xpos[0]) * view[0]/2; - xpos[1] = (1 + xpos[1]) * view[1]/2; - SbVec3f ypos; - comb.multVecMatrix(SbVec3f(0,1,0), ypos); - ypos[0] = (1 + ypos[0]) * view[0]/2; - ypos[1] = (1 + ypos[1]) * view[1]/2; - SbVec3f zpos; - comb.multVecMatrix(SbVec3f(0,0,1), zpos); - zpos[0] = (1 + zpos[0]) * view[0]/2; - zpos[1] = (1 + zpos[1]) * view[1]/2; - - - // Render the cross. - { - glLineWidth(2.0); - - enum { XAXIS, YAXIS, ZAXIS }; - int idx[3] = { XAXIS, YAXIS, ZAXIS }; - float val[3] = { xpos[2], ypos[2], zpos[2] }; - - // Bubble sort.. :-} - if (val[0] < val[1]) { - std::swap(val[0], val[1]); - std::swap(idx[0], idx[1]); - } - - if (val[1] < val[2]) { - std::swap(val[1], val[2]); - std::swap(idx[1], idx[2]); - } - - if (val[0] < val[1]) { - std::swap(val[0], val[1]); - std::swap(idx[0], idx[1]); - } - - assert((val[0] >= val[1]) && (val[1] >= val[2])); // Just checking.. - - for(int i=0; i < 3; i++) { - glPushMatrix(); - - if (idx[i] == XAXIS) { // X axis. - if(stereoMode() != Quarter::SoQTQuarterAdaptor::MONO) - glColor3f(0.500f, 0.5f, 0.5f); - else - glColor3f(0.500f, 0.125f, 0.125f); - } - else if (idx[i] == YAXIS) { // Y axis. - glRotatef(90, 0, 0, 1); - - if (stereoMode() != Quarter::SoQTQuarterAdaptor::MONO) - glColor3f(0.400f, 0.4f, 0.4f); - else - glColor3f(0.125f, 0.500f, 0.125f); - } - else { // Z axis. - glRotatef(-90, 0, 1, 0); - - if (stereoMode() != Quarter::SoQTQuarterAdaptor::MONO) - glColor3f(0.300f, 0.3f, 0.3f); - else - glColor3f(0.125f, 0.125f, 0.500f); - } - - this->drawArrow(); - glPopMatrix(); - } - } - - // Render axis notation letters ("X", "Y", "Z"). - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(0, view[0], 0, view[1], -1, 1); - - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - - GLint unpack; - glGetIntegerv(GL_UNPACK_ALIGNMENT, &unpack); - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - - if (stereoMode() != Quarter::SoQTQuarterAdaptor::MONO) - glColor3fv(SbVec3f(1.0f, 1.0f, 1.0f).getValue()); - else - glColor3fv(SbVec3f(0.0f, 0.0f, 0.0f).getValue()); - - glRasterPos2d(xpos[0], xpos[1]); - glBitmap(8, 7, 0, 0, 0, 0, xbmp); - glRasterPos2d(ypos[0], ypos[1]); - glBitmap(8, 7, 0, 0, 0, 0, ybmp); - glRasterPos2d(zpos[0], zpos[1]); - glBitmap(8, 7, 0, 0, 0, 0, zbmp); - - glPixelStorei(GL_UNPACK_ALIGNMENT, unpack); - glPopMatrix(); - - // Reset original state. - - // FIXME: are these 3 lines really necessary, as we push - // GL_ALL_ATTRIB_BITS at the start? 20000604 mortene. - glDepthRange(depthrange[0], depthrange[1]); - glMatrixMode(GL_PROJECTION); - glLoadMatrixd(projectionmatrix); - - glPopAttrib(); -} - -// Draw an arrow for the axis representation directly through OpenGL. -void View3DInventorViewer::drawArrow(void) -{ - glBegin(GL_LINES); - glVertex3f(0.0f, 0.0f, 0.0f); - glVertex3f(1.0f, 0.0f, 0.0f); - glEnd(); - glDisable(GL_CULL_FACE); - glBegin(GL_TRIANGLES); - glVertex3f(1.0f, 0.0f, 0.0f); - glVertex3f(1.0f - 1.0f / 3.0f, +0.5f / 4.0f, 0.0f); - glVertex3f(1.0f - 1.0f / 3.0f, -0.5f / 4.0f, 0.0f); - glVertex3f(1.0f, 0.0f, 0.0f); - glVertex3f(1.0f - 1.0f / 3.0f, 0.0f, +0.5f / 4.0f); - glVertex3f(1.0f - 1.0f / 3.0f, 0.0f, -0.5f / 4.0f); - glEnd(); - glBegin(GL_QUADS); - glVertex3f(1.0f - 1.0f / 3.0f, +0.5f / 4.0f, 0.0f); - glVertex3f(1.0f - 1.0f / 3.0f, 0.0f, +0.5f / 4.0f); - glVertex3f(1.0f - 1.0f / 3.0f, -0.5f / 4.0f, 0.0f); - glVertex3f(1.0f - 1.0f / 3.0f, 0.0f, -0.5f / 4.0f); - glEnd(); -} - -// ************************************************************************ -#if 0 -#define HAND_WITH 24 -#define HAND_HEIGHT 24 -#define HAND_HOT_X 9 -#define HAND_HOT_Y 0 - -static unsigned char hand_bitmap[] = { - 0x00,0x03,0x00,0x80,0x04,0x00,0x80,0x04,0x00,0x80,0x04,0x00,0x80,0x04,0x00, - 0x80,0x1c,0x00,0x80,0xe4,0x00,0x80,0x24,0x01,0x80,0x24,0x07,0x8e,0x24,0x09, - 0x92,0x24,0x09,0xa4,0x00,0x09,0xc4,0x00,0x08,0x08,0x00,0x08,0x08,0x00,0x08, - 0x10,0x00,0x08,0x10,0x00,0x04,0x20,0x00,0x04,0x20,0x00,0x04,0x40,0x00,0x02, - 0x80,0x00,0x02,0x00,0x01,0x01,0x00,0xff,0x01,0x00,0x00,0x00,0x00,0xab,0xab, - 0xab,0xab,0xab,0xab,0xab,0xab,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02, - 0x00,0x1b,0x00,0xee,0x04,0xee -}; - -static unsigned char hand_mask_bitmap[] = { - 0x00,0x03,0x00,0x80,0x07,0x00,0x80,0x07,0x00,0x80,0x07,0x00,0x80,0x07,0x00, - 0x80,0x1f,0x00,0x80,0xff,0x00,0x80,0xff,0x01,0x80,0xff,0x07,0x8e,0xff,0x0f, - 0x9e,0xff,0x0f,0xbc,0xff,0x0f,0xfc,0xff,0x0f,0xf8,0xff,0x0f,0xf8,0xff,0x0f, - 0xf0,0xff,0x0f,0xf0,0xff,0x07,0xe0,0xff,0x07,0xe0,0xff,0x07,0xc0,0xff,0x03, - 0x80,0xff,0x03,0x00,0xff,0x01,0x00,0xff,0x01,0x00,0x00,0x00,0x00,0xab,0xab, - 0xab,0xab,0xab,0xab,0xab,0xab,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05, - 0x00,0x1b,0x00,0xd5,0x07,0x1c -}; - -#define CROSS_WIDTH 16 -#define CROSS_HEIGHT 16 -#define CROSS_HOT_X 7 -#define CROSS_HOT_Y 7 - -static unsigned char cross_bitmap[] = { - 0xc0, 0x03, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, - 0x40, 0x02, 0x40, 0x02, 0x7f, 0xfe, 0x01, 0x80, - 0x01, 0x80, 0x7f, 0xfe, 0x40, 0x02, 0x40, 0x02, - 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0xc0, 0x03 -}; - -static unsigned char cross_mask_bitmap[] = { - 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, - 0xc0, 0x03, 0xc0, 0x03, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xc0, 0x03, 0xc0, 0x03, - 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03 -}; -#endif -// Set cursor graphics according to mode. -void View3DInventorViewer::setCursorRepresentation(int modearg) -{ - // There is a synchronization problem between Qt and SoQt which - // happens when popping up a context-menu. In this case the - // Qt::WA_UnderMouse attribute is resetted and never set again - // even if the mouse is still in the canvas. Thus, the cursor - // won't be changed as long as the user doesn't leave and enter - // the canvas. To fix this we explicitly set Qt::WA_UnderMouse - // if the mouse is inside the canvas. - QWidget* w = this->getGLWidget(); - - if (w && w->rect().contains(QCursor::pos())) - w->setAttribute(Qt::WA_UnderMouse); - - switch(modearg) { - case NavigationStyle::IDLE: - case NavigationStyle::INTERACT: - if(isEditing()) - this->getWidget()->setCursor(this->editCursor); - else - this->getWidget()->setCursor(QCursor(Qt::ArrowCursor)); - - break; - - case NavigationStyle::DRAGGING: - case NavigationStyle::SPINNING: - this->getWidget()->setCursor(spinCursor); - break; - - case NavigationStyle::ZOOMING: - { - this->getWidget()->setCursor(zoomCursor); - } - break; - - case NavigationStyle::SEEK_MODE: - case NavigationStyle::SEEK_WAIT_MODE: - case NavigationStyle::BOXZOOM: - { - this->getWidget()->setCursor(Qt::CrossCursor); - } - break; - - case NavigationStyle::PANNING: - this->getWidget()->setCursor(panCursor); - break; - - case NavigationStyle::SELECTION: - { - this->getWidget()->setCursor(Qt::PointingHandCursor); - } - break; - - default: - assert(0); - break; - } -} - -void View3DInventorViewer::setEditing(SbBool edit) -{ - this->editing = edit; - this->getWidget()->setCursor(QCursor(Qt::ArrowCursor)); - this->editCursor = QCursor(); -} - -void View3DInventorViewer::setEditingCursor(const QCursor& cursor) -{ - this->getWidget()->setCursor(cursor); - this->editCursor = this->getWidget()->cursor(); -} - -void View3DInventorViewer::setComponentCursor(QCursor cursor) -{ - this->getWidget()->setCursor(cursor); -} - - -void View3DInventorViewer::selectCB(void* viewer, SoPath* path) -{ - ViewProvider* vp = static_cast(viewer)->getViewProviderByPath(path); - - if (vp && vp->useNewSelectionModel()) { - } -} - -void View3DInventorViewer::deselectCB(void* viewer, SoPath* path) -{ - ViewProvider* vp = static_cast(viewer)->getViewProviderByPath(path); - - if (vp && vp->useNewSelectionModel()) { - } -} - -SoPath* View3DInventorViewer::pickFilterCB(void* viewer, const SoPickedPoint* pp) -{ - ViewProvider* vp = static_cast(viewer)->getViewProviderByPath(pp->getPath()); - - if (vp && vp->useNewSelectionModel()) { - std::string e = vp->getElement(pp->getDetail()); - vp->getSelectionShape(e.c_str()); - static char buf[513]; - snprintf(buf,512,"Hovered: %s (%f,%f,%f)" - ,e.c_str() - ,pp->getPoint()[0] - ,pp->getPoint()[1] - ,pp->getPoint()[2]); - - getMainWindow()->showMessage(QString::fromLatin1(buf),3000); - } - - return pp->getPath(); -} - -void View3DInventorViewer::addEventCallback(SoType eventtype, SoEventCallbackCB* cb, void* userdata) -{ - pEventCallback->addEventCallback(eventtype, cb, userdata); -} - -void View3DInventorViewer::removeEventCallback(SoType eventtype, SoEventCallbackCB* cb, void* userdata) -{ - pEventCallback->removeEventCallback(eventtype, cb, userdata); -} - -ViewProvider* View3DInventorViewer::getViewProviderByPath(SoPath* path) const -{ - // FIXME Use the viewprovider map introduced for the selection - for(std::set::const_iterator it = _ViewProviderSet.begin(); it != _ViewProviderSet.end(); ++it) { - for(int i = 0; igetLength(); i++) { - SoNode* node = path->getNode(i); - - if ((*it)->getRoot() == node) { - return (*it); - } - } - } - - return 0; -} - -ViewProvider* View3DInventorViewer::getViewProviderByPathFromTail(SoPath* path) const -{ - // Make sure I'm the lowest LocHL in the pick path! - for(int i = 0; i < path->getLength(); i++) { - SoNode* node = path->getNodeFromTail(i); - - if (node->isOfType(SoSeparator::getClassTypeId())) { - std::map::const_iterator it = _ViewProviderMap.find(static_cast(node)); - - if (it != _ViewProviderMap.end()) { - return it->second; - } - } - } - - return 0; -} - -std::vector View3DInventorViewer::getViewProvidersOfType(const Base::Type& typeId) const -{ - std::vector views; - - for(std::set::const_iterator it = _ViewProviderSet.begin(); it != _ViewProviderSet.end(); ++it) { - if((*it)->getTypeId().isDerivedFrom(typeId)) { - views.push_back(*it); - } - } - - return views; -} - -void View3DInventorViewer::turnAllDimensionsOn() -{ - dimensionRoot->whichChild = SO_SWITCH_ALL; -} - -void View3DInventorViewer::turnAllDimensionsOff() -{ - dimensionRoot->whichChild = SO_SWITCH_NONE; -} - -void View3DInventorViewer::eraseAllDimensions() -{ - static_cast(dimensionRoot->getChild(0))->removeAllChildren(); - static_cast(dimensionRoot->getChild(1))->removeAllChildren(); -} - -void View3DInventorViewer::turn3dDimensionsOn() -{ - static_cast(dimensionRoot->getChild(0))->whichChild = SO_SWITCH_ALL; -} - -void View3DInventorViewer::turn3dDimensionsOff() -{ - static_cast(dimensionRoot->getChild(0))->whichChild = SO_SWITCH_NONE; -} - -void View3DInventorViewer::addDimension3d(SoNode* node) -{ - static_cast(dimensionRoot->getChild(0))->addChild(node); -} - -void View3DInventorViewer::addDimensionDelta(SoNode* node) -{ - static_cast(dimensionRoot->getChild(1))->addChild(node); -} - -void View3DInventorViewer::turnDeltaDimensionsOn() -{ - static_cast(dimensionRoot->getChild(1))->whichChild = SO_SWITCH_ALL; -} - -void View3DInventorViewer::turnDeltaDimensionsOff() -{ - static_cast(dimensionRoot->getChild(1))->whichChild = SO_SWITCH_NONE; -} - -PyObject *View3DInventorViewer::getPyObject(void) -{ - if (!_viewerPy) - _viewerPy = new View3DInventorViewerPy(this); - - Py_INCREF(_viewerPy); - return _viewerPy; -} diff --git a/src/Mod/Assembly/App/AppAssemblyPy.cpp.orig b/src/Mod/Assembly/App/AppAssemblyPy.cpp.orig deleted file mode 100644 index 6fc5870fb..000000000 --- a/src/Mod/Assembly/App/AppAssemblyPy.cpp.orig +++ /dev/null @@ -1,98 +0,0 @@ -/*************************************************************************** - * Copyright (c) 2008 Jürgen Riegel (juergen.riegel@web.de) * - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file COPYING.LIB. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * - ***************************************************************************/ - - -#include "PreCompiled.h" -#ifndef _PreComp_ -# include -#endif - -#include -#include - -#include - -#include -#include -#include - -#include - -#include "ViewProviderBody.h" -#include "Utils.h" - - -//static PyObject * setActiveBody(PyObject *self, PyObject *args) -//{ -// PyObject *object=0; -// if (PyArg_ParseTuple(args,"|O!",&(PartDesign::BodyPy::Type), &object)&& object) { -// PartDesign::Body* Item = static_cast(object)->getBodyPtr(); -// // Should be set! -// assert(Item); -// -// // Set old body inactive if we are activating another body in the same document -// if ((PartDesignGui::ActivePartObject != NULL) && -// (PartDesignGui::ActivePartObject->getDocument() == Item->getDocument())) -// PartDesignGui::ActivePartObject->IsActive.setValue(false); -// PartDesignGui::ActivePartObject = Item; -// PartDesignGui::ActiveAppDoc = Item->getDocument(); -// PartDesignGui::ActiveGuiDoc = Gui::Application::Instance->getDocument(PartDesignGui::ActiveAppDoc); -// PartDesignGui::ActiveVp = dynamic_cast (PartDesignGui::ActiveGuiDoc->getViewProvider(Item)); -// PartDesignGui::ActiveVp->show(); -// Item->IsActive.setValue(true); -// } else { -// // This handles the case of deactivating the workbench -// PartDesignGui::ActivePartObject=0; -// PartDesignGui::ActiveGuiDoc =0; -// PartDesignGui::ActiveAppDoc =0; -// PartDesignGui::ActiveVp =0; -// } -// -// Py_Return; -//} -// -//static PyObject * getActiveBody(PyObject *, PyObject *) -//{ -// if (PartDesignGui::ActivePartObject == NULL) { -// return Py::_None(); -// } -// -// return PartDesignGui::ActivePartObject->getPyObject(); -//} - -/* registration table */ -struct PyMethodDef Assembly_methods[] = { - //{"setActiveBody" ,setActiveBody ,METH_VARARGS, - // "setActiveBody(BodyObject) -- Set the PartBody object in work."}, - - //{"getActiveBody" ,getActiveBody ,METH_NOARGS, - // "getActiveBody() -- Get the PartBody object in work."}, - -<<<<<<< f03c0f9bdef9886ee45a086b02fa7ebaa99b6825:src/Mod/Assembly/App/AppAssemblyPy.cpp - {"setUpPart" ,setUpPart ,METH_VARARGS, - "setUpPart(Part) -- Sets a empty part object up for usage in PartDesign."}, - - {NULL, NULL} /* end of table marker */ -======= - {NULL, NULL} /* end of table marker */ ->>>>>>> OriginGroup: add new abstraction layer between the Part and the GeoFeatureGroup:src/Mod/PartDesign/Gui/AppPartDesignGuiPy.cpp -}; diff --git a/src/Mod/Assembly/Gui/Resources/Assembly.qrc.orig b/src/Mod/Assembly/Gui/Resources/Assembly.qrc.orig deleted file mode 100644 index 0af9ed22d..000000000 --- a/src/Mod/Assembly/Gui/Resources/Assembly.qrc.orig +++ /dev/null @@ -1,81 +0,0 @@ -<<<<<<< d6421cef81c1d7a191d1524d88c63e56e3f6d864 - - - icons/Assembly_ConstraintLock.svg - icons/Assembly_ConstraintDistance.svg - icons/Assembly_ConstraintAngle.svg - icons/Assembly_ConstraintOrientation.svg - icons/Assembly_ConstraintCoincidence.svg - icons/Assembly_ConstraintAlignment.svg - translations/Assembly_af.qm - translations/Assembly_de.qm - translations/Assembly_fi.qm - translations/Assembly_fr.qm - translations/Assembly_hr.qm - translations/Assembly_it.qm - translations/Assembly_nl.qm - translations/Assembly_no.qm - translations/Assembly_ru.qm - translations/Assembly_uk.qm - translations/Assembly_tr.qm - translations/Assembly_sv-SE.qm - translations/Assembly_pl.qm - translations/Assembly_zh-TW.qm - translations/Assembly_pt-BR.qm - translations/Assembly_cs.qm - translations/Assembly_sk.qm - translations/Assembly_es-ES.qm - translations/Assembly_zh-CN.qm - translations/Assembly_ja.qm - translations/Assembly_ro.qm - translations/Assembly_hu.qm - translations/Assembly_pt-PT.qm - translations/Assembly_sr.qm - translations/Assembly_el.qm - translations/Assembly_sl.qm - - -======= - - - icons/Assembly_ConstraintBidirectional.svg - icons/Assembly_ConstraintUnidirectional1.svg - icons/Assembly_ConstraintUnidirectional2.svg - icons/Assembly_ConstraintPerpendicular.svg - icons/Assembly_ConstraintParallel.svg - icons/Assembly_ConstraintOpposite.svg - icons/Assembly_ConstraintEqual.svg - icons/Assembly_ConstraintLock.svg - icons/Assembly_ConstraintDistance.svg - icons/Assembly_ConstraintAngle.svg - icons/Assembly_ConstraintOrientation.svg - icons/Assembly_ConstraintCoincidence.svg - icons/Assembly_ConstraintAlignment.svg - icons/Assembly_ConstraintGeneral.svg - translations/Assembly_af.qm - translations/Assembly_de.qm - translations/Assembly_fi.qm - translations/Assembly_fr.qm - translations/Assembly_hr.qm - translations/Assembly_it.qm - translations/Assembly_nl.qm - translations/Assembly_no.qm - translations/Assembly_ru.qm - translations/Assembly_uk.qm - translations/Assembly_tr.qm - translations/Assembly_sv-SE.qm - translations/Assembly_pl.qm - translations/Assembly_zh-TW.qm - translations/Assembly_pt-BR.qm - translations/Assembly_cs.qm - translations/Assembly_sk.qm - translations/Assembly_es-ES.qm - translations/Assembly_zh-CN.qm - translations/Assembly_ja.qm - translations/Assembly_ro.qm - translations/Assembly_hu.qm - translations/Assembly_pt-PT.qm - translations/Assembly_sr.qm - - ->>>>>>> revidsed assembly constraint gui interaction diff --git a/src/Mod/Import/App/AppImportPy.cpp.orig b/src/Mod/Import/App/AppImportPy.cpp.orig deleted file mode 100644 index dbad1b6ac..000000000 --- a/src/Mod/Import/App/AppImportPy.cpp.orig +++ /dev/null @@ -1,664 +0,0 @@ -/*************************************************************************** - * Copyright (c) 2013 Werner Mayer * - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file COPYING.LIB. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * - ***************************************************************************/ - - -#include "PreCompiled.h" -#if defined(__MINGW32__) -# define WNT // avoid conflict with GUID -#endif -#ifndef _PreComp_ -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -#endif - -#include -#include - -#include "ImportOCAF.h" -//#include "ImportOCAFAssembly.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -<<<<<<< e2142800e3730f3726818e80efa9d0c125b57558 -namespace Import { -class Module : public Py::ExtensionModule -{ -public: - Module() : Py::ExtensionModule("Import") - { - add_varargs_method("open",&Module::importer, - "open(string) -- Open the file and create a new document." - ); - add_varargs_method("insert",&Module::importer, - "insert(string,string) -- Insert the file into the given document." - ); - add_varargs_method("openAssembly",&Module::importAssembly, - "openAssembly(string) -- Open the assembly file and create a new document." - ); - add_varargs_method("export",&Module::exporter, - "export(list,string) -- Export a list of objects into a single file." - ); - initialize("This module is the Import module."); // register with Python - - if(TargetObjectPy) - target = static_cast(TargetObjectPy)->getDocumentObjectPtr(); - - } - - virtual ~Module() {} - -private: - Py::Object importer(const Py::Tuple& args) - - { - char* Name; - char* DocName=0; - if (!PyArg_ParseTuple(args.ptr(), "et|s","utf-8",&Name,&DocName)) - throw Py::Exception(); - - std::string Utf8Name = std::string(Name); - PyMem_Free(Name); - std::string name8bit = Part::encodeFilename(Utf8Name); - - try { - //Base::Console().Log("Insert in Part with %s",Name); - Base::FileInfo file(Utf8Name.c_str()); - - App::Document *pcDoc = 0; - if (DocName) { - pcDoc = App::GetApplication().getDocument(DocName); - } - if (!pcDoc) { - pcDoc = App::GetApplication().newDocument("Unnamed"); - } - - Handle(XCAFApp_Application) hApp = XCAFApp_Application::GetApplication(); - Handle(TDocStd_Document) hDoc; - hApp->NewDocument(TCollection_ExtendedString("MDTV-CAF"), hDoc); - - if (file.hasExtension("stp") || file.hasExtension("step")) { - try { - STEPCAFControl_Reader aReader; - aReader.SetColorMode(true); - aReader.SetNameMode(true); - aReader.SetLayerMode(true); - if (aReader.ReadFile((Standard_CString)(name8bit.c_str())) != IFSelect_RetDone) { - throw Py::Exception(PyExc_IOError, "cannot read STEP file"); - } - - Handle_Message_ProgressIndicator pi = new Part::ProgressIndicator(100); - aReader.Reader().WS()->MapReader()->SetProgress(pi); - pi->NewScope(100, "Reading STEP file..."); - pi->Show(); - aReader.Transfer(hDoc); - pi->EndScope(); - } - catch (OSD_Exception) { - Handle_Standard_Failure e = Standard_Failure::Caught(); - Base::Console().Error("%s\n", e->GetMessageString()); - Base::Console().Message("Try to load STEP file without colors...\n"); - - Part::ImportStepParts(pcDoc,Utf8Name.c_str()); - pcDoc->recompute(); - } - } - else if (file.hasExtension("igs") || file.hasExtension("iges")) { - Base::Reference hGrp = App::GetApplication().GetUserParameter() - .GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/Part")->GetGroup("IGES"); - - try { - IGESControl_Controller::Init(); - IGESCAFControl_Reader aReader; - // http://www.opencascade.org/org/forum/thread_20603/?forum=3 - aReader.SetReadVisible(hGrp->GetBool("SkipBlankEntities", true) - ? Standard_True : Standard_False); - aReader.SetColorMode(true); - aReader.SetNameMode(true); - aReader.SetLayerMode(true); - if (aReader.ReadFile((Standard_CString)(name8bit.c_str())) != IFSelect_RetDone) { - throw Py::Exception(PyExc_IOError, "cannot read IGES file"); - } - - Handle_Message_ProgressIndicator pi = new Part::ProgressIndicator(100); - aReader.WS()->MapReader()->SetProgress(pi); - pi->NewScope(100, "Reading IGES file..."); - pi->Show(); - aReader.Transfer(hDoc); - pi->EndScope(); - } - catch (OSD_Exception) { - Handle_Standard_Failure e = Standard_Failure::Caught(); - Base::Console().Error("%s\n", e->GetMessageString()); - Base::Console().Message("Try to load IGES file without colors...\n"); - - Part::ImportIgesParts(pcDoc,Utf8Name.c_str()); - pcDoc->recompute(); - } - } - else { - throw Py::Exception(Base::BaseExceptionFreeCADError, "no supported file format"); - } - -#if 1 - Import::ImportOCAF ocaf(hDoc, pcDoc, file.fileNamePure()); - ocaf.loadShapes(); -#else - Import::ImportXCAF xcaf(hDoc, pcDoc, file.fileNamePure()); - xcaf.loadShapes(); -#endif - pcDoc->recompute(); - } - catch (Standard_Failure) { - Handle_Standard_Failure e = Standard_Failure::Caught(); - throw Py::Exception(Base::BaseExceptionFreeCADError, e->GetMessageString()); - } - catch (const Base::Exception& e) { - throw Py::RuntimeError(e.what()); - } - - return Py::None(); - } - Py::Object exporter(const Py::Tuple& args) - { - PyObject* object; - char* Name; - if (!PyArg_ParseTuple(args.ptr(), "Oet",&object,"utf-8",&Name)) - throw Py::Exception(); - - std::string Utf8Name = std::string(Name); - PyMem_Free(Name); - std::string name8bit = Part::encodeFilename(Utf8Name); - - try { - Handle(XCAFApp_Application) hApp = XCAFApp_Application::GetApplication(); - Handle(TDocStd_Document) hDoc; - hApp->NewDocument(TCollection_ExtendedString("MDTV-CAF"), hDoc); - Import::ExportOCAF ocaf(hDoc); - - Py::Sequence list(object); - for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) { - PyObject* item = (*it).ptr(); - if (PyObject_TypeCheck(item, &(App::DocumentObjectPy::Type))) { - App::DocumentObject* obj = static_cast(item)->getDocumentObjectPtr(); - if (obj->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) { - Part::Feature* part = static_cast(obj); - std::vector colors; - ocaf.saveShape(part, colors); - } - else { - Base::Console().Message("'%s' is not a shape, export will be ignored.\n", obj->Label.getValue()); - } - } - else if (PyTuple_Check(item) && PyTuple_Size(item) == 2) { - Py::Tuple tuple(*it); - Py::Object item0 = tuple.getItem(0); - Py::Object item1 = tuple.getItem(1); - if (PyObject_TypeCheck(item0.ptr(), &(App::DocumentObjectPy::Type))) { - App::DocumentObject* obj = static_cast(item0.ptr())->getDocumentObjectPtr(); - if (obj->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) { - Part::Feature* part = static_cast(obj); - App::PropertyColorList colors; - colors.setPyObject(item1.ptr()); - ocaf.saveShape(part, colors.getValues()); - } - else { - Base::Console().Message("'%s' is not a shape, export will be ignored.\n", obj->Label.getValue()); - } - } - } - } - - Base::FileInfo file(Utf8Name.c_str()); - if (file.hasExtension("stp") || file.hasExtension("step")) { - //Interface_Static::SetCVal("write.step.schema", "AP214IS"); - STEPCAFControl_Writer writer; - writer.Transfer(hDoc, STEPControl_AsIs); - - // edit STEP header -#if OCC_VERSION_HEX >= 0x060500 - APIHeaderSection_MakeHeader makeHeader(writer.ChangeWriter().Model()); -#else - APIHeaderSection_MakeHeader makeHeader(writer.Writer().Model()); -#endif - Base::Reference hGrp = App::GetApplication().GetUserParameter() - .GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/Part")->GetGroup("STEP"); - - makeHeader.SetName(new TCollection_HAsciiString((const Standard_CString)Utf8Name.c_str())); - makeHeader.SetAuthorValue (1, new TCollection_HAsciiString(hGrp->GetASCII("Author", "Author").c_str())); - makeHeader.SetOrganizationValue (1, new TCollection_HAsciiString(hGrp->GetASCII("Company").c_str())); - makeHeader.SetOriginatingSystem(new TCollection_HAsciiString(App::GetApplication().getExecutableName())); - makeHeader.SetDescriptionValue(1, new TCollection_HAsciiString("FreeCAD Model")); - IFSelect_ReturnStatus ret = writer.Write(name8bit.c_str()); - if (ret == IFSelect_RetError || ret == IFSelect_RetFail || ret == IFSelect_RetStop) { - PyErr_Format(PyExc_IOError, "Cannot open file '%s'", Utf8Name.c_str()); - throw Py::Exception(); - } - } - else if (file.hasExtension("igs") || file.hasExtension("iges")) { - IGESControl_Controller::Init(); - IGESCAFControl_Writer writer; - IGESData_GlobalSection header = writer.Model()->GlobalSection(); - header.SetAuthorName(new TCollection_HAsciiString(Interface_Static::CVal("write.iges.header.author"))); - header.SetCompanyName(new TCollection_HAsciiString(Interface_Static::CVal("write.iges.header.company"))); - header.SetSendName(new TCollection_HAsciiString(Interface_Static::CVal("write.iges.header.product"))); - writer.Model()->SetGlobalSection(header); - writer.Transfer(hDoc); - Standard_Boolean ret = writer.Write(name8bit.c_str()); - if (!ret) { - PyErr_Format(PyExc_IOError, "Cannot open file '%s'", Utf8Name.c_str()); - throw Py::Exception(); - } - } - } - catch (Standard_Failure) { - Handle_Standard_Failure e = Standard_Failure::Caught(); - throw Py::Exception(Base::BaseExceptionFreeCADError, e->GetMessageString()); - } - catch (const Base::Exception& e) { - throw Py::RuntimeError(e.what()); - } - - return Py::None(); - } - {"importAssembly" ,importAssembly ,METH_VARARGS, - "importAssembly(FileName,Target) -- Import a Assembly file and creates a Assembly structure."}, -}; - -======= -/* module functions */ -/* ->>>>>>> remove import dependency on assembly workbench -static PyObject * importAssembly(PyObject *self, PyObject *args) -{ - char* Name; - PyObject* TargetObjectPy=0; - if (!PyArg_ParseTuple(args, "et|O!","utf-8",&Name,&(App::DocumentObjectPy::Type),&TargetObjectPy)) - return 0; - std::string Utf8Name = std::string(Name); - PyMem_Free(Name); - std::string name8bit = Part::encodeFilename(Utf8Name); - - PY_TRY { - //Base::Console().Log("Insert in Part with %s",Name); - Base::FileInfo file(name8bit); - - App::DocumentObject* target = nullptr; - - if(TargetObjectPy) - target = static_cast(TargetObjectPy)->getDocumentObjectPtr(); - - - App::Document *pcDoc = 0; - - pcDoc = App::GetApplication().getActiveDocument(); - - if (!pcDoc) - pcDoc = App::GetApplication().newDocument("ImportedAssembly"); - - - Handle(XCAFApp_Application) hApp = XCAFApp_Application::GetApplication(); - Handle(TDocStd_Document) hDoc; - hApp->NewDocument(TCollection_ExtendedString("MDTV-CAF"), hDoc); - - if (file.hasExtension("stp") || file.hasExtension("step")) { - try { - STEPCAFControl_Reader aReader; - aReader.SetColorMode(true); - aReader.SetNameMode(true); - aReader.SetLayerMode(true); - if (aReader.ReadFile((Standard_CString)(name8bit.c_str())) != IFSelect_RetDone) { - PyErr_SetString(PyExc_Exception, "cannot read STEP file"); - return 0; - } - - Handle_Message_ProgressIndicator pi = new Part::ProgressIndicator(100); - aReader.Reader().WS()->MapReader()->SetProgress(pi); - pi->NewScope(100, "Reading STEP file..."); - pi->Show(); - aReader.Transfer(hDoc); - pi->EndScope(); - } - catch (OSD_Exception) { - Handle_Standard_Failure e = Standard_Failure::Caught(); - Base::Console().Error("%s\n", e->GetMessageString()); - Base::Console().Message("Try to load STEP file without colors...\n"); - - Part::ImportStepParts(pcDoc,Name); - pcDoc->recompute(); - } - } - else if (file.hasExtension("igs") || file.hasExtension("iges")) { - try { - IGESControl_Controller::Init(); - Interface_Static::SetIVal("read.surfacecurve.mode",3); - IGESCAFControl_Reader aReader; - aReader.SetColorMode(true); - aReader.SetNameMode(true); - aReader.SetLayerMode(true); - if (aReader.ReadFile((Standard_CString)(name8bit.c_str())) != IFSelect_RetDone) { - PyErr_SetString(PyExc_Exception, "cannot read IGES file"); - return 0; - } - - Handle_Message_ProgressIndicator pi = new Part::ProgressIndicator(100); - aReader.WS()->MapReader()->SetProgress(pi); - pi->NewScope(100, "Reading IGES file..."); - pi->Show(); - aReader.Transfer(hDoc); - pi->EndScope(); - } - catch (OSD_Exception) { - Handle_Standard_Failure e = Standard_Failure::Caught(); - Base::Console().Error("%s\n", e->GetMessageString()); - Base::Console().Message("Try to load IGES file without colors...\n"); - - Part::ImportIgesParts(pcDoc,Name); - pcDoc->recompute(); - } - } - else { - PyErr_SetString(PyExc_Exception, "no supported file format"); - return 0; - } - - Import::ImportOCAFAssembly ocaf(hDoc, pcDoc, file.fileNamePure(),target); - ocaf.loadAssembly(); - pcDoc->recompute(); - - } - catch (Standard_Failure) { - Handle_Standard_Failure e = Standard_Failure::Caught(); - PyErr_SetString(PyExc_Exception, e->GetMessageString()); - return 0; - } - PY_CATCH - - Py_Return; -}*/ - - - -static PyObject * importer(PyObject *self, PyObject *args) -{ - char* Name; - char* DocName=0; - if (!PyArg_ParseTuple(args, "et|s","utf-8",&Name,&DocName)) - return NULL; - std::string Utf8Name = std::string(Name); - PyMem_Free(Name); - std::string name8bit = Part::encodeFilename(Utf8Name); - - PY_TRY { - //Base::Console().Log("Insert in Part with %s",Name); - Base::FileInfo file(Utf8Name.c_str()); - - App::Document *pcDoc = 0; - if (DocName) { - pcDoc = App::GetApplication().getDocument(DocName); - } - if (!pcDoc) { - pcDoc = App::GetApplication().newDocument("Unnamed"); - } - - Handle(XCAFApp_Application) hApp = XCAFApp_Application::GetApplication(); - Handle(TDocStd_Document) hDoc; - hApp->NewDocument(TCollection_ExtendedString("MDTV-CAF"), hDoc); - - if (file.hasExtension("stp") || file.hasExtension("step")) { - try { - STEPCAFControl_Reader aReader; - aReader.SetColorMode(true); - aReader.SetNameMode(true); - aReader.SetLayerMode(true); - if (aReader.ReadFile((Standard_CString)(name8bit.c_str())) != IFSelect_RetDone) { - PyErr_SetString(Base::BaseExceptionFreeCADError, "cannot read STEP file"); - return 0; - } - - Handle_Message_ProgressIndicator pi = new Part::ProgressIndicator(100); - aReader.Reader().WS()->MapReader()->SetProgress(pi); - pi->NewScope(100, "Reading STEP file..."); - pi->Show(); - aReader.Transfer(hDoc); - pi->EndScope(); - } - catch (OSD_Exception) { - Handle_Standard_Failure e = Standard_Failure::Caught(); - Base::Console().Error("%s\n", e->GetMessageString()); - Base::Console().Message("Try to load STEP file without colors...\n"); - - Part::ImportStepParts(pcDoc,Utf8Name.c_str()); - pcDoc->recompute(); - } - } - else if (file.hasExtension("igs") || file.hasExtension("iges")) { - Base::Reference hGrp = App::GetApplication().GetUserParameter() - .GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/Part")->GetGroup("IGES"); - - try { - IGESControl_Controller::Init(); - IGESCAFControl_Reader aReader; - // http://www.opencascade.org/org/forum/thread_20603/?forum=3 - aReader.SetReadVisible(hGrp->GetBool("SkipBlankEntities", true) - ? Standard_True : Standard_False); - aReader.SetColorMode(true); - aReader.SetNameMode(true); - aReader.SetLayerMode(true); - if (aReader.ReadFile((Standard_CString)(name8bit.c_str())) != IFSelect_RetDone) { - PyErr_SetString(Base::BaseExceptionFreeCADError, "cannot read IGES file"); - return 0; - } - - Handle_Message_ProgressIndicator pi = new Part::ProgressIndicator(100); - aReader.WS()->MapReader()->SetProgress(pi); - pi->NewScope(100, "Reading IGES file..."); - pi->Show(); - aReader.Transfer(hDoc); - pi->EndScope(); - } - catch (OSD_Exception) { - Handle_Standard_Failure e = Standard_Failure::Caught(); - Base::Console().Error("%s\n", e->GetMessageString()); - Base::Console().Message("Try to load IGES file without colors...\n"); - - Part::ImportIgesParts(pcDoc,Utf8Name.c_str()); - pcDoc->recompute(); - } - } - else { - PyErr_SetString(Base::BaseExceptionFreeCADError, "no supported file format"); - return 0; - } - -#if 1 - Import::ImportOCAF ocaf(hDoc, pcDoc, file.fileNamePure()); - ocaf.loadShapes(); -#else - Import::ImportXCAF xcaf(hDoc, pcDoc, file.fileNamePure()); - xcaf.loadShapes(); -#endif - pcDoc->recompute(); - - } - catch (Standard_Failure) { - Handle_Standard_Failure e = Standard_Failure::Caught(); - PyErr_SetString(Base::BaseExceptionFreeCADError, e->GetMessageString()); - return 0; - } - PY_CATCH - - Py_Return; -} - -static PyObject * open(PyObject *self, PyObject *args) -{ - return importer(self, args); -} - -static PyObject * exporter(PyObject *self, PyObject *args) -{ - PyObject* object; - char* Name; - if (!PyArg_ParseTuple(args, "Oet",&object,"utf-8",&Name)) - return NULL; - std::string Utf8Name = std::string(Name); - PyMem_Free(Name); - std::string name8bit = Part::encodeFilename(Utf8Name); - - PY_TRY { - Handle(XCAFApp_Application) hApp = XCAFApp_Application::GetApplication(); - Handle(TDocStd_Document) hDoc; - hApp->NewDocument(TCollection_ExtendedString("MDTV-CAF"), hDoc); - Import::ExportOCAF ocaf(hDoc); - - Py::Sequence list(object); - for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) { - PyObject* item = (*it).ptr(); - if (PyObject_TypeCheck(item, &(App::DocumentObjectPy::Type))) { - App::DocumentObject* obj = static_cast(item)->getDocumentObjectPtr(); - if (obj->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) { - Part::Feature* part = static_cast(obj); - std::vector colors; - ocaf.saveShape(part, colors); - } - else { - Base::Console().Message("'%s' is not a shape, export will be ignored.\n", obj->Label.getValue()); - } - } - else if (PyTuple_Check(item) && PyTuple_Size(item) == 2) { - Py::Tuple tuple(*it); - Py::Object item0 = tuple.getItem(0); - Py::Object item1 = tuple.getItem(1); - if (PyObject_TypeCheck(item0.ptr(), &(App::DocumentObjectPy::Type))) { - App::DocumentObject* obj = static_cast(item0.ptr())->getDocumentObjectPtr(); - if (obj->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) { - Part::Feature* part = static_cast(obj); - App::PropertyColorList colors; - colors.setPyObject(item1.ptr()); - ocaf.saveShape(part, colors.getValues()); - } - else { - Base::Console().Message("'%s' is not a shape, export will be ignored.\n", obj->Label.getValue()); - } - } - } - } - - Base::FileInfo file(Utf8Name.c_str()); - if (file.hasExtension("stp") || file.hasExtension("step")) { - //Interface_Static::SetCVal("write.step.schema", "AP214IS"); - STEPCAFControl_Writer writer; - writer.Transfer(hDoc, STEPControl_AsIs); - - // edit STEP header -#if OCC_VERSION_HEX >= 0x060500 - APIHeaderSection_MakeHeader makeHeader(writer.ChangeWriter().Model()); -#else - APIHeaderSection_MakeHeader makeHeader(writer.Writer().Model()); -#endif - Base::Reference hGrp = App::GetApplication().GetUserParameter() - .GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/Part")->GetGroup("STEP"); - - makeHeader.SetName(new TCollection_HAsciiString((const Standard_CString)Utf8Name.c_str())); - makeHeader.SetAuthorValue (1, new TCollection_HAsciiString(hGrp->GetASCII("Author", "Author").c_str())); - makeHeader.SetOrganizationValue (1, new TCollection_HAsciiString(hGrp->GetASCII("Company").c_str())); - makeHeader.SetOriginatingSystem(new TCollection_HAsciiString(App::GetApplication().getExecutableName())); - makeHeader.SetDescriptionValue(1, new TCollection_HAsciiString("FreeCAD Model")); - IFSelect_ReturnStatus ret = writer.Write(name8bit.c_str()); - if (ret == IFSelect_RetError || ret == IFSelect_RetFail || ret == IFSelect_RetStop) { - PyErr_Format(PyExc_IOError, "Cannot open file '%s'", Utf8Name.c_str()); - return 0; - } - } - else if (file.hasExtension("igs") || file.hasExtension("iges")) { - IGESControl_Controller::Init(); - IGESCAFControl_Writer writer; - IGESData_GlobalSection header = writer.Model()->GlobalSection(); - header.SetAuthorName(new TCollection_HAsciiString(Interface_Static::CVal("write.iges.header.author"))); - header.SetCompanyName(new TCollection_HAsciiString(Interface_Static::CVal("write.iges.header.company"))); - header.SetSendName(new TCollection_HAsciiString(Interface_Static::CVal("write.iges.header.product"))); - writer.Model()->SetGlobalSection(header); - writer.Transfer(hDoc); - Standard_Boolean ret = writer.Write(name8bit.c_str()); - if (!ret) { - PyErr_Format(PyExc_IOError, "Cannot open file '%s'", Utf8Name.c_str()); - return 0; - } - } - } - catch (Standard_Failure) { - Handle_Standard_Failure e = Standard_Failure::Caught(); - PyErr_SetString(Base::BaseExceptionFreeCADError, e->GetMessageString()); - return 0; - } - PY_CATCH - - Py_Return; -} - -<<<<<<< e2142800e3730f3726818e80efa9d0c125b57558 -PyObject* initModule() -{ - return (new Module)->module().ptr(); -} - -} // namespace Import -======= -/* registration table */ -struct PyMethodDef Import_Import_methods[] = { - {"open" ,open ,METH_VARARGS, - "open(string) -- Open the file and create a new document."}, - {"insert" ,importer ,METH_VARARGS, - "insert(string,string) -- Insert the file into the given document."}, - {"export" ,exporter ,METH_VARARGS, - "export(list,string) -- Export a list of objects into a single file."}, -// {"importAssembly" ,importAssembly ,METH_VARARGS, -// "importAssembly(FileName,Target) -- Import a Assembly file and creates a Assembly structure."}, - {NULL, NULL} /* end of table marker */ -}; ->>>>>>> remove import dependency on assembly workbench diff --git a/src/Mod/PartDesign/App/AppPartDesign.cpp.orig b/src/Mod/PartDesign/App/AppPartDesign.cpp.orig deleted file mode 100644 index 6ad46eda6..000000000 --- a/src/Mod/PartDesign/App/AppPartDesign.cpp.orig +++ /dev/null @@ -1,118 +0,0 @@ -/*************************************************************************** - * Copyright (c) 2008 Jürgen Riegel (juergen.riegel@web.de) * - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file COPYING.LIB. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * - ***************************************************************************/ - - -#include "PreCompiled.h" -#ifndef _PreComp_ -# include -#endif - -#include -#include - -#include "FeaturePad.h" -#include "FeatureSolid.h" -#include "FeaturePocket.h" -#include "FeatureFillet.h" -#include "FeatureSketchBased.h" -#include "FeatureRevolution.h" -#include "FeatureGroove.h" -#include "Body.h" -#include "FeatureDressUp.h" -#include "FeatureChamfer.h" -#include "FeatureDraft.h" -<<<<<<< c3c1399b7e8f8ceea8f3c1288ebfe0b6575f4d90 -#include "FeatureSubtractive.h" -#include "FeatureAdditive.h" -======= -#include "FeatureFace.h" ->>>>>>> allow non-sketch based additive and subtractive features -#include "FeatureTransformed.h" -#include "FeatureMirrored.h" -#include "FeatureLinearPattern.h" -#include "FeaturePolarPattern.h" -#include "FeatureScaled.h" -#include "FeatureMultiTransform.h" -#include "FeatureHole.h" -#include "DatumPlane.h" -#include "DatumLine.h" -#include "DatumPoint.h" -#include "FeatureBoolean.h" - -extern struct PyMethodDef PartDesign_methods[]; - -PyDoc_STRVAR(module_PartDesign_doc, -"This module is the PartDesign module."); - - -/* Python entry */ -extern "C" { -void PartDesignExport init_PartDesign() -{ - // load dependent module - try { - Base::Interpreter().runString("import Part"); - Base::Interpreter().runString("import Sketcher"); - } - catch(const Base::Exception& e) { - PyErr_SetString(PyExc_ImportError, e.what()); - return; - } - Py_InitModule3("_PartDesign", PartDesign_methods, module_PartDesign_doc); /* mod name, table ptr */ - Base::Console().Log("Loading PartDesign module... done\n"); - - - // NOTE: To finish the initialization of our own type objects we must - // call PyType_Ready, otherwise we run into a segmentation fault, later on. - // This function is responsible for adding inherited slots from a type's base class. - - PartDesign::Feature ::init(); - PartDesign::Solid ::init(); - PartDesign::DressUp ::init(); - PartDesign::FeatureAddSub ::init(); - PartDesign::SketchBased ::init(); - PartDesign::Transformed ::init(); - PartDesign::Mirrored ::init(); - PartDesign::LinearPattern ::init(); - PartDesign::PolarPattern ::init(); - PartDesign::Scaled ::init(); - PartDesign::MultiTransform ::init(); - PartDesign::Hole ::init(); - PartDesign::Body ::init(); - PartDesign::Pad ::init(); - PartDesign::Pocket ::init(); - PartDesign::Fillet ::init(); - PartDesign::Revolution ::init(); - PartDesign::Groove ::init(); - PartDesign::Chamfer ::init(); - PartDesign::Draft ::init(); - PartDesign::Plane ::init(); - PartDesign::Line ::init(); - PartDesign::Point ::init(); - PartDesign::Boolean ::init(); - - PartDesign::Point::initHints(); - PartDesign::Line ::initHints(); - PartDesign::Plane::initHints(); -} - -} // extern "C" diff --git a/src/Mod/PartDesign/App/FeatureChamfer.cpp.orig b/src/Mod/PartDesign/App/FeatureChamfer.cpp.orig deleted file mode 100644 index 063bcc439..000000000 --- a/src/Mod/PartDesign/App/FeatureChamfer.cpp.orig +++ /dev/null @@ -1,153 +0,0 @@ -/*************************************************************************** - * Copyright (c) 2010 Juergen Riegel * - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file COPYING.LIB. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * - ***************************************************************************/ - - -#include "PreCompiled.h" -#ifndef _PreComp_ -# include -# include -# include -# include -# include -# include -# include -#endif - -<<<<<<< 50287516b47694e57429cc98f6d5596a06a635d6 -#include -#include -======= -#include ->>>>>>> Some code unification for DressUp features -#include - -#include "FeatureChamfer.h" - - -using namespace PartDesign; - - -PROPERTY_SOURCE(PartDesign::Chamfer, PartDesign::DressUp) - -const App::PropertyQuantityConstraint::Constraints floatSize = {0.0,FLT_MAX,0.1}; - -Chamfer::Chamfer() -{ - ADD_PROPERTY(Size,(1.0)); - Size.setUnit(Base::Unit::Length); - Size.setConstraints(&floatSize); -} - -short Chamfer::mustExecute() const -{ - if (Placement.isTouched() || Size.isTouched()) - return 1; - return DressUp::mustExecute(); -} - -App::DocumentObjectExecReturn *Chamfer::execute(void) -{ - // NOTE: Normally the Base property and the BaseFeature property should point to the same object. - // The only difference is that the Base property also stores the edges that are to be chamfered - Part::TopoShape TopShape; - try { - TopShape = getBaseShape(); - } catch (Base::Exception& e) { - return new App::DocumentObjectExecReturn(e.what()); - } - - const std::vector& SubVals = Base.getSubValuesStartsWith("Edge"); - if (SubVals.size() == 0) - return new App::DocumentObjectExecReturn("No edges specified"); - - double size = Size.getValue(); - - this->positionByBaseFeature(); - // create an untransformed copy of the basefeature shape - Part::TopoShape baseShape(TopShape); - baseShape.setTransform(Base::Matrix4D()); - try { - BRepFilletAPI_MakeChamfer mkChamfer(baseShape._Shape); - - TopTools_IndexedMapOfShape mapOfEdges; - TopTools_IndexedDataMapOfShapeListOfShape mapEdgeFace; - TopExp::MapShapesAndAncestors(baseShape._Shape, TopAbs_EDGE, TopAbs_FACE, mapEdgeFace); - TopExp::MapShapes(baseShape._Shape, TopAbs_EDGE, mapOfEdges); - - for (std::vector::const_iterator it=SubVals.begin(); it != SubVals.end(); ++it) { - TopoDS_Edge edge = TopoDS::Edge(baseShape.getSubShape(it->c_str())); - const TopoDS_Face& face = TopoDS::Face(mapEdgeFace.FindFromKey(edge).First()); - mkChamfer.Add(size, edge, face); - } - - mkChamfer.Build(); - if (!mkChamfer.IsDone()) - return new App::DocumentObjectExecReturn("Failed to create chamfer"); - - TopoDS_Shape shape = mkChamfer.Shape(); - if (shape.IsNull()) - return new App::DocumentObjectExecReturn("Resulting shape is null"); - - this->Shape.setValue(shape); - return App::DocumentObject::StdReturn; - } - catch (Standard_Failure) { - Handle_Standard_Failure e = Standard_Failure::Caught(); - return new App::DocumentObjectExecReturn(e->GetMessageString()); - } -} - -void Chamfer::Restore(Base::XMLReader &reader) -{ - reader.readElement("Properties"); - int Cnt = reader.getAttributeAsInteger("Count"); - - for (int i=0 ;igetTypeId().getName(), TypeName) == 0) { - prop->Restore(reader); - } - else if (prop && strcmp(TypeName,"App::PropertyFloatConstraint") == 0 && - strcmp(prop->getTypeId().getName(), "App::PropertyQuantityConstraint") == 0) { - App::PropertyFloatConstraint p; - p.Restore(reader); - static_cast(prop)->setValue(p.getValue()); - } - } - catch (const Base::XMLParseException&) { - throw; // re-throw - } - catch (const Base::Exception &e) { - Base::Console().Error("%s\n", e.what()); - } - catch (const std::exception &e) { - Base::Console().Error("%s\n", e.what()); - } - reader.readEndElement("Property"); - } - reader.readEndElement("Properties"); -} diff --git a/src/Mod/PartDesign/App/FeatureDressUp.cpp.orig b/src/Mod/PartDesign/App/FeatureDressUp.cpp.orig deleted file mode 100644 index 723e4b652..000000000 --- a/src/Mod/PartDesign/App/FeatureDressUp.cpp.orig +++ /dev/null @@ -1,171 +0,0 @@ -/*************************************************************************** - * Copyright (c) 2010 Juergen Riegel * - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file COPYING.LIB. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * - ***************************************************************************/ - - -#include "PreCompiled.h" -#ifndef _PreComp_ -#endif - - -#include "FeatureDressUp.h" -#include -#include -#include -#include -#include -#include -#include - - -using namespace PartDesign; - -namespace PartDesign { - - -PROPERTY_SOURCE(PartDesign::DressUp, PartDesign::Feature) - -DressUp::DressUp() -{ - ADD_PROPERTY(Base,(0)); - Placement.StatusBits.set(2, true); -} - -short DressUp::mustExecute() const -{ - if (Base.getValue() && Base.getValue()->isTouched()) - return 1; - return PartDesign::Feature::mustExecute(); -} - - -void DressUp::positionByBaseFeature(void) -{ - Part::Feature *base = static_cast(BaseFeature.getValue()); - if (base && base->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) - this->Placement.setValue(base->Placement.getValue()); -} - -Part::TopoShape DressUp::getBaseShape() -{ - App::DocumentObject* link = BaseFeature.getValue(); - if (!link) - link = this->Base.getValue(); // For legacy features - if (!link) - throw Base::Exception("No object linked"); - if (!link->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) - throw Base::Exception("Linked object is not a Part object"); - Part::Feature* base = static_cast(link); - const Part::TopoShape& shape = base->Shape.getShape(); - if (shape._Shape.IsNull()) - throw Base::Exception("Cannot draft invalid shape"); - return shape; -} - -void DressUp::getContiniusEdges(Part::TopoShape TopShape, std::vector< std::string >& SubNames) { - - TopTools_IndexedMapOfShape mapOfEdges; - TopTools_IndexedDataMapOfShapeListOfShape mapEdgeFace; - TopExp::MapShapesAndAncestors(TopShape._Shape, TopAbs_EDGE, TopAbs_FACE, mapEdgeFace); - TopExp::MapShapes(TopShape._Shape, TopAbs_EDGE, mapOfEdges); - - unsigned int i = 0; - while(i < SubNames.size()) - { - std::string aSubName = static_cast(SubNames.at(i)); - - if (aSubName.size() > 4 && aSubName.substr(0,4) == "Edge") { - TopoDS_Edge edge = TopoDS::Edge(TopShape.getSubShape(aSubName.c_str())); - const TopTools_ListOfShape& los = mapEdgeFace.FindFromKey(edge); - - if(los.Extent() != 2) - { - SubNames.erase(SubNames.begin()+i); - continue; - } - - const TopoDS_Shape& face1 = los.First(); - const TopoDS_Shape& face2 = los.Last(); - GeomAbs_Shape cont = BRep_Tool::Continuity(TopoDS::Edge(edge), - TopoDS::Face(face1), - TopoDS::Face(face2)); - if (cont != GeomAbs_C0) { - SubNames.erase(SubNames.begin()+i); - continue; - } - - i++; - } - else if(aSubName.size() > 4 && aSubName.substr(0,4) == "Face") { - TopoDS_Face face = TopoDS::Face(TopShape.getSubShape(aSubName.c_str())); - - TopTools_IndexedMapOfShape mapOfFaces; - TopExp::MapShapes(face, TopAbs_EDGE, mapOfFaces); - - for(int j = 1; j <= mapOfFaces.Extent(); ++j) { - TopoDS_Edge edge = TopoDS::Edge(mapOfFaces.FindKey(j)); - - int id = mapOfEdges.FindIndex(edge); - - std::stringstream buf; - buf << "Edge"; - buf << id; - - if(std::find(SubNames.begin(),SubNames.end(),buf.str()) == SubNames.end()) - { - SubNames.push_back(buf.str()); - } - - } - - SubNames.erase(SubNames.begin()+i); - } - // empty name or any other sub-element - else { - SubNames.erase(SubNames.begin()+i); - } - } -} - - -void DressUp::onChanged(const App::Property* prop) -{ - // the BaseFeature property should always link to the same feature as the Base - if (prop == &BaseFeature) { -<<<<<<< 3108a1b6d1b9743ebed7c154a07a695bb7207a5d - // if attached to a sketch then mark it as read-only - this->Placement.setStatus(App::Property::ReadOnly, BaseFeature.getValue() != 0); -======= - if (Base.getValue() != BaseFeature.getValue()) { - Base.setValue (BaseFeature.getValue()); - } - } else if (prop == &Base) { - // track the vice-versa changes - if (Base.getValue() != BaseFeature.getValue()) { - BaseFeature.setValue (Base.getValue()); - } ->>>>>>> PartDesign/FeatureDressUp: make Base and BaseFeature properties track the same feature - } - - Feature::onChanged(prop); -} - -} diff --git a/src/Mod/PartDesign/App/FeatureFillet.cpp.orig b/src/Mod/PartDesign/App/FeatureFillet.cpp.orig deleted file mode 100644 index e92edeedb..000000000 --- a/src/Mod/PartDesign/App/FeatureFillet.cpp.orig +++ /dev/null @@ -1,155 +0,0 @@ -/*************************************************************************** - * Copyright (c) 2008 Werner Mayer * - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file COPYING.LIB. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * - ***************************************************************************/ - - -#include "PreCompiled.h" -#ifndef _PreComp_ -# include -# include -# include -# include -# include -<<<<<<< 2c7cc8276bd6dd4ccc4aa28daa809a688bd493c5 -# include -======= -#include -#include -#include ->>>>>>> allow to add faces to fillet and chamfer -#endif - -#include -#include -#include -#include - -#include "FeatureFillet.h" - - -using namespace PartDesign; - - -PROPERTY_SOURCE(PartDesign::Fillet, PartDesign::DressUp) - -const App::PropertyQuantityConstraint::Constraints floatRadius = {0.0,FLT_MAX,0.1}; - -Fillet::Fillet() -{ - ADD_PROPERTY(Radius,(1.0)); - Radius.setUnit(Base::Unit::Length); - Radius.setConstraints(&floatRadius); -} - -short Fillet::mustExecute() const -{ - if (Placement.isTouched() || Radius.isTouched()) - return 1; - return DressUp::mustExecute(); -} - -App::DocumentObjectExecReturn *Fillet::execute(void) -{ - Part::TopoShape TopShape; - try { - TopShape = getBaseShape(); - } catch (Base::Exception& e) { - return new App::DocumentObjectExecReturn(e.what()); - } - std::vector SubNames = std::vector(Base.getSubValues()); - getContiniusEdges(TopShape, SubNames); - - if (SubNames.size() == 0) - return new App::DocumentObjectExecReturn("Fillet not possible on selected shapes"); - - double radius = Radius.getValue(); - - this->positionByBaseFeature(); - - // create an untransformed copy of the base shape - Part::TopoShape baseShape(TopShape); - baseShape.setTransform(Base::Matrix4D()); - try { - BRepFilletAPI_MakeFillet mkFillet(baseShape._Shape); - - for (std::vector::const_iterator it=SubNames.begin(); it != SubNames.end(); ++it) { - TopoDS_Edge edge = TopoDS::Edge(baseShape.getSubShape(it->c_str())); - mkFillet.Add(radius, edge); - } - - mkFillet.Build(); - if (!mkFillet.IsDone()) - return new App::DocumentObjectExecReturn("Failed to create fillet"); - - TopoDS_Shape shape = mkFillet.Shape(); - if (shape.IsNull()) - return new App::DocumentObjectExecReturn("Resulting shape is null"); - - TopTools_ListOfShape aLarg; - aLarg.Append(baseShape._Shape); - if (!BRepAlgo::IsValid(aLarg, shape, Standard_False, Standard_False)) { - return new App::DocumentObjectExecReturn("Resulting shape is invalid"); - } - - this->Shape.setValue(shape); - return App::DocumentObject::StdReturn; - } - catch (Standard_Failure) { - Handle_Standard_Failure e = Standard_Failure::Caught(); - return new App::DocumentObjectExecReturn(e->GetMessageString()); - } -} - -void Fillet::Restore(Base::XMLReader &reader) -{ - reader.readElement("Properties"); - int Cnt = reader.getAttributeAsInteger("Count"); - - for (int i=0 ;igetTypeId().getName(), TypeName) == 0) { - prop->Restore(reader); - } - else if (prop && strcmp(TypeName,"App::PropertyFloatConstraint") == 0 && - strcmp(prop->getTypeId().getName(), "App::PropertyQuantityConstraint") == 0) { - App::PropertyFloatConstraint p; - p.Restore(reader); - static_cast(prop)->setValue(p.getValue()); - } - } - catch (const Base::XMLParseException&) { - throw; // re-throw - } - catch (const Base::Exception &e) { - Base::Console().Error("%s\n", e.what()); - } - catch (const std::exception &e) { - Base::Console().Error("%s\n", e.what()); - } - reader.readEndElement("Property"); - } - reader.readEndElement("Properties"); -} diff --git a/src/Mod/PartDesign/Gui/Command.cpp.orig b/src/Mod/PartDesign/Gui/Command.cpp.orig deleted file mode 100644 index c9b80865f..000000000 --- a/src/Mod/PartDesign/Gui/Command.cpp.orig +++ /dev/null @@ -1,1934 +0,0 @@ -/*************************************************************************** - * Copyright (c) 2008 Jürgen Riegel (juergen.riegel@web.de) * - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file COPYING.LIB. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * - ***************************************************************************/ - - -#include "PreCompiled.h" - -#ifndef _PreComp_ -# include -# include -# include -# include -# include -#endif - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "TaskFeaturePick.h" -#include "ReferenceSelection.h" -#include "Utils.h" -#include "WorkflowManager.h" - -// TODO Remove this header after fixing code so it won;t be needed here (2015-10-20, Fat-Zer) -#include "ui_DlgReference.h" - -using namespace std; - - -//=========================================================================== -// PartDesign_Datum -//=========================================================================== - -/** - * @brief UnifiedDatumCommand is a common routine called by datum plane, line and point commands - * @param cmd (i/o) command, to have shortcuts to doCommand, etc. - * @param type (input) - * @param name (input). Is used to generate new name for an object, and to fill undo messages. - * - */ -void UnifiedDatumCommand(Gui::Command &cmd, Base::Type type, std::string name) -{ - try{ - std::string fullTypeName (type.getName()); - - App::PropertyLinkSubList support; - cmd.getSelection().getAsPropertyLinkSubList(support); - - bool bEditSelected = false; - if (support.getSize() == 1 && support.getValue() ) { - if (support.getValue()->isDerivedFrom(type)) - bEditSelected = true; - } - - PartDesign::Body *pcActiveBody = PartDesignGui::getBody(/*messageIfNot = */false); - - if (bEditSelected) { - std::string tmp = std::string("Edit ")+name; - cmd.openCommand(tmp.c_str()); - cmd.doCommand(Gui::Command::Gui,"Gui.activeDocument().setEdit('%s')",support.getValue()->getNameInDocument()); - } else if (pcActiveBody) { - - auto pcActivePart = PartDesignGui::getPartFor(pcActiveBody, false); - - // TODO Check how this will work outside of a body (2015-10-20, Fat-Zer) - //check the prerequisites for the selected objects - //the user has to decide which option we should take if external references are used - bool ext = false; - for(App::DocumentObject* obj : support.getValues()) { - if(!pcActiveBody->hasFeature(obj)) - ext = true; - } - // TODO rewrite this to be shared with CmdPartDesignNewSketch::activated() (2015-10-20, Fat-Zer) - if(ext) { - QDialog* dia = new QDialog; - Ui_Dialog dlg; - dlg.setupUi(dia); - dia->setModal(true); - int result = dia->exec(); - if(result == QDialog::DialogCode::Rejected) - return; - else if(!dlg.radioXRef->isChecked()) { - - std::vector objs; - std::vector subs = support.getSubValues(); - int index = 0; - for(App::DocumentObject* obj : support.getValues()) { - - objs.push_back(PartDesignGui::TaskFeaturePick::makeCopy(obj, subs[index], dlg.radioIndependent->isChecked())); - auto oBody = PartDesignGui::getBodyFor(obj, false); - if (oBody && pcActiveBody) { - pcActiveBody->addFeature(objs.back()); - } else if (pcActivePart) { - pcActivePart->addObject(objs.back()); - } - - } - } - - }; - - std::string FeatName = cmd.getUniqueObjectName(name.c_str()); - - std::string tmp = std::string("Create ")+name; - - cmd.openCommand(tmp.c_str()); - cmd.doCommand(Gui::Command::Doc,"App.activeDocument().addObject('%s','%s')",fullTypeName.c_str(),FeatName.c_str()); - - //test if current selection fits a mode. - if (support.getSize() > 0) { - AttachableObject* pcDatum = static_cast(cmd.getDocument()->getObject(FeatName.c_str())); - pcDatum->attacher().references.Paste(support); - eSuggestResult msg; - eMapMode suggMode = pcDatum->attacher().listMapModes(msg); - if (msg == srOK) { - //fits some mode. Populate support property. - cmd.doCommand(Gui::Command::Doc,"App.activeDocument().%s.Support = %s",FeatName.c_str(),support.getPyReprString().c_str()); - cmd.doCommand(Gui::Command::Doc,"App.activeDocument().%s.MapMode = '%s'",FeatName.c_str(),AttachEngine::eMapModeStrings[suggMode]); - } else { - QMessageBox::information(Gui::getMainWindow(),QObject::tr("Invalid selection"), QObject::tr("There are no attachment modes that fit seleted objects. Select something else.")); - } - } - if (pcActiveBody) { - cmd.doCommand(Gui::Command::Doc,"App.activeDocument().%s.addFeature(App.activeDocument().%s)", - pcActiveBody->getNameInDocument(), FeatName.c_str()); - } - cmd.doCommand(Gui::Command::Doc,"App.activeDocument().recompute()"); // recompute the feature based on its references - cmd.doCommand(Gui::Command::Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); - } - } catch (Base::Exception &e) { - QMessageBox::warning(Gui::getMainWindow(),QObject::tr("Error"),QString::fromLatin1(e.what())); - } catch (Standard_Failure &e) { - QMessageBox::warning(Gui::getMainWindow(),QObject::tr("Error"),QString::fromLatin1(e.GetMessageString())); - } -} - -/* Datum feature commands =======================================================*/ - -DEF_STD_CMD_A(CmdPartDesignPlane); - -CmdPartDesignPlane::CmdPartDesignPlane() - :Command("PartDesign_Plane") -{ - sAppModule = "PartDesign"; - sGroup = QT_TR_NOOP("PartDesign"); - sMenuText = QT_TR_NOOP("Create a datum plane"); - sToolTipText = QT_TR_NOOP("Create a new datum plane"); - sWhatsThis = sToolTipText; - sStatusTip = sToolTipText; - sPixmap = "PartDesign_Plane"; -} - -void CmdPartDesignPlane::activated(int iMsg) -{ - UnifiedDatumCommand(*this, Base::Type::fromName("PartDesign::Plane"),"DatumPlane"); -} - -bool CmdPartDesignPlane::isActive(void) -{ - if (getActiveGuiDocument()) - return true; - else - return false; -} - -DEF_STD_CMD_A(CmdPartDesignLine); - -CmdPartDesignLine::CmdPartDesignLine() - :Command("PartDesign_Line") -{ - sAppModule = "PartDesign"; - sGroup = QT_TR_NOOP("PartDesign"); - sMenuText = QT_TR_NOOP("Create a datum line"); - sToolTipText = QT_TR_NOOP("Create a new datum line"); - sWhatsThis = sToolTipText; - sStatusTip = sToolTipText; - sPixmap = "PartDesign_Line"; -} - -void CmdPartDesignLine::activated(int iMsg) -{ - UnifiedDatumCommand(*this, Base::Type::fromName("PartDesign::Line"),"DatumLine"); -} - -bool CmdPartDesignLine::isActive(void) -{ - if (getActiveGuiDocument()) - return true; - else - return false; -} - -DEF_STD_CMD_A(CmdPartDesignPoint); - -CmdPartDesignPoint::CmdPartDesignPoint() - :Command("PartDesign_Point") -{ - sAppModule = "PartDesign"; - sGroup = QT_TR_NOOP("PartDesign"); - sMenuText = QT_TR_NOOP("Create a datum point"); - sToolTipText = QT_TR_NOOP("Create a new datum point"); - sWhatsThis = sToolTipText; - sStatusTip = sToolTipText; - sPixmap = "PartDesign_Point"; -} - -void CmdPartDesignPoint::activated(int iMsg) -{ - UnifiedDatumCommand(*this, Base::Type::fromName("PartDesign::Point"),"DatumPoint"); -} - -bool CmdPartDesignPoint::isActive(void) -{ - if (getActiveGuiDocument()) - return true; - else - return false; -} - -//=========================================================================== -// PartDesign_ShapeBinder -//=========================================================================== - -DEF_STD_CMD_A(CmdPartDesignShapeBinder); - -CmdPartDesignShapeBinder::CmdPartDesignShapeBinder() - :Command("PartDesign_ShapeBinder") -{ - sAppModule = "PartDesign"; - sGroup = QT_TR_NOOP("PartDesign"); - sMenuText = QT_TR_NOOP("Create a shape binder"); - sToolTipText = QT_TR_NOOP("Create a new shape binder"); - sWhatsThis = sToolTipText; - sStatusTip = sToolTipText; - sPixmap = "PartDesign_ShapeBinder"; -} - -void CmdPartDesignShapeBinder::activated(int iMsg) -{ - App::PropertyLinkSubList support; - getSelection().getAsPropertyLinkSubList(support); - - bool bEditSelected = false; - if (support.getSize() == 1 && support.getValue() ){ - if (support.getValue()->isDerivedFrom(PartDesign::ShapeBinder::getClassTypeId()) || - support.getValue()->isDerivedFrom(PartDesign::ShapeBinder2D::getClassTypeId())) - bEditSelected = true; - } - - if (bEditSelected) { - // TODO probably we not should handle edit here (2015-10-26, Fat-Zer) - std::string tmp = std::string("Edit ShapeBinder"); - openCommand(tmp.c_str()); - doCommand(Gui::Command::Gui,"Gui.activeDocument().setEdit('%s')", - support.getValue()->getNameInDocument()); - } else { - PartDesign::Body *pcActiveBody = PartDesignGui::getBody(/*messageIfNot = */true); - if (pcActiveBody == 0) - return; - - std::string FeatName = getUniqueObjectName("ShapeBinder"); - std::string tmp = std::string("Create ShapeBinder"); - - openCommand(tmp.c_str()); - - if(support.getValue()->isDerivedFrom(PartDesign::ShapeBinder2D::getClassTypeId()) || - support.getValue()->isDerivedFrom(Part::Part2DObject::getClassTypeId())) { - doCommand(Gui::Command::Doc,"App.activeDocument().addObject('%s','%s')", - "PartDesign::ShapeBinder2D",FeatName.c_str()); - } else { - doCommand(Gui::Command::Doc,"App.activeDocument().addObject('%s','%s')", - "PartDesign::ShapeBinder",FeatName.c_str()); - } - - //test if current selection fits a mode. - if (support.getSize() > 0) { - AttachableObject* pcDatum = static_cast( - getDocument()->getObject(FeatName.c_str())); - doCommand(Gui::Command::Doc,"App.activeDocument().%s.Support = %s", - FeatName.c_str(),support.getPyReprString().c_str()); - } - doCommand(Gui::Command::Doc,"App.activeDocument().%s.addFeature(App.activeDocument().%s)", - pcActiveBody->getNameInDocument(), FeatName.c_str()); - doCommand(Gui::Command::Doc,"App.activeDocument().recompute()"); // recompute the feature based on its references - doCommand(Gui::Command::Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); - } - // TODO do a proper error processing (2015-09-11, Fat-Zer) -} - -bool CmdPartDesignShapeBinder::isActive(void) -{ - return hasActiveDocument (); -} - -//=========================================================================== -// PartDesign_Sketch -//=========================================================================== - -/* Sketch commands =======================================================*/ -DEF_STD_CMD_A(CmdPartDesignNewSketch); - -CmdPartDesignNewSketch::CmdPartDesignNewSketch() - :Command("PartDesign_NewSketch") -{ - sAppModule = "PartDesign"; - sGroup = QT_TR_NOOP("PartDesign"); - sMenuText = QT_TR_NOOP("Create sketch"); - sToolTipText = QT_TR_NOOP("Create a new sketch"); - sWhatsThis = sToolTipText; - sStatusTip = sToolTipText; - sPixmap = "Sketcher_NewSketch"; -} - - -void CmdPartDesignNewSketch::activated(int iMsg) -{ - App::Document *doc = getDocument (); - PartDesign::Body *pcActiveBody = PartDesignGui::getBody( - /*messageIfNot = */ PartDesignGui::assureModernWorkflow ( doc ) ); - - // No PartDesign feature without Body past FreeCAD 0.13 - if ( !pcActiveBody ) { - // Call normal sketch command for old workflow - if ( PartDesignGui::isLegacyWorkflow ( doc) ) { - Gui::CommandManager &rcCmdMgr = Gui::Application::Instance->commandManager(); - rcCmdMgr.runCommandByName("Sketcher_NewSketch"); - } - return; - } - - Gui::SelectionFilter SketchFilter("SELECT Sketcher::SketchObject COUNT 1"); - Gui::SelectionFilter FaceFilter ("SELECT Part::Feature SUBELEMENT Face COUNT 1"); - Gui::SelectionFilter PlaneFilter ("SELECT App::Plane COUNT 1"); - Gui::SelectionFilter PlaneFilter2("SELECT PartDesign::Plane COUNT 1"); - if (PlaneFilter2.match()) - PlaneFilter = PlaneFilter2; - - if (SketchFilter.match()) { - Sketcher::SketchObject *Sketch = static_cast(SketchFilter.Result[0][0].getObject()); - openCommand("Edit Sketch"); - doCommand(Gui,"Gui.activeDocument().setEdit('%s')",Sketch->getNameInDocument()); - } - else if (FaceFilter.match() || PlaneFilter.match()) { - // get the selected object - std::string supportString; - App::DocumentObject* obj; - - if (FaceFilter.match()) { - obj = FaceFilter.Result[0][0].getObject(); - - if(!obj->isDerivedFrom(Part::Feature::getClassTypeId())) - return; - - Part::Feature* feat = static_cast(obj); - - const std::vector &sub = FaceFilter.Result[0][0].getSubNames(); - if (sub.size() > 1) { - // No assert for wrong user input! - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Several sub-elements selected"), - QObject::tr("You have to select a single face as support for a sketch!")); - return; - } - - // get the selected sub shape (a Face) - const Part::TopoShape &shape = feat->Shape.getValue(); - TopoDS_Shape sh = shape.getSubShape(sub[0].c_str()); - const TopoDS_Face& face = TopoDS::Face(sh); - if (face.IsNull()) { - // No assert for wrong user input! - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No support face selected"), - QObject::tr("You have to select a face as support for a sketch!")); - return; - } - - BRepAdaptor_Surface adapt(face); - if (adapt.GetType() != GeomAbs_Plane){ - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No planar support"), - QObject::tr("You need a planar face as support for a sketch!")); - return; - } - - supportString = FaceFilter.Result[0][0].getAsPropertyLinkSubString(); - } else { - obj = static_cast(PlaneFilter.Result[0][0].getObject()); - supportString = std::string("(App.activeDocument().") + obj->getNameInDocument() + ", '')"; - } - - if (!pcActiveBody->hasFeature(obj)) { - if ( !obj->isDerivedFrom ( App::Plane::getClassTypeId() ) ) { - // TODO check here if the plane associated with right part/body (2015-09-01, Fat-Zer) - - auto pcActivePart = PartDesignGui::getPartFor(pcActiveBody, false); - - //check the prerequisites for the selected objects - //the user has to decide which option we should take if external references are used - // TODO share this with UnifiedDatumCommand() (2015-10-20, Fat-Zer) - QDialog* dia = new QDialog; - Ui_Dialog dlg; - dlg.setupUi(dia); - dia->setModal(true); - int result = dia->exec(); - if(result == QDialog::DialogCode::Rejected) - return; - else if(!dlg.radioXRef->isChecked()) { - - const std::vector &sub = FaceFilter.Result[0][0].getSubNames(); - auto copy = PartDesignGui::TaskFeaturePick::makeCopy(obj, sub[0], dlg.radioIndependent->isChecked()); - auto oBody = PartDesignGui::getBodyFor(obj, false); - if(oBody) - pcActiveBody->addFeature(copy); - else - pcActivePart->addObject(copy); - } - } - } - - // create Sketch on Face or Plane - std::string FeatName = getUniqueObjectName("Sketch"); - - openCommand("Create a Sketch on Face"); - doCommand(Doc,"App.activeDocument().addObject('Sketcher::SketchObject','%s')",FeatName.c_str()); - doCommand(Doc,"App.activeDocument().%s.Support = %s",FeatName.c_str(),supportString.c_str()); - doCommand(Doc,"App.activeDocument().%s.MapMode = '%s'",FeatName.c_str(),Attacher::AttachEngine::eMapModeStrings[Attacher::mmFlatFace]); - doCommand(Doc,"App.activeDocument().%s.addFeature(App.activeDocument().%s)", - pcActiveBody->getNameInDocument(), FeatName.c_str()); - doCommand(Gui,"App.activeDocument().recompute()"); // recompute the sketch placement based on its support - //doCommand(Gui,"Gui.activeDocument().activeView().setCamera('%s')",cam.c_str()); - doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); - } - else { - // Get a valid plane from the user - unsigned validPlanes = 0; - - App::GeoFeatureGroup* geoGroup = App::GeoFeatureGroup::getGroupOfObject ( pcActiveBody ); - - std::vector planes; - std::vector status; - - // Baseplanes are preaprooved - if ( pcActiveBody ) { - try { - for ( auto plane: pcActiveBody->getOrigin ()->planes() ) { - planes.push_back (plane); - status.push_back(PartDesignGui::TaskFeaturePick::basePlane); - validPlanes++; - } - } catch (const Base::Exception &ex) { - Base::Console().Error ("%s\n", ex.what() ); - } - } - - std::vector datumPlanes = - getDocument()->getObjectsOfType(PartDesign::Plane::getClassTypeId()); - - for (auto plane: datumPlanes) { - planes.push_back ( plane ); - // Check whether this plane belongs to the active body - if ( pcActiveBody && pcActiveBody->hasFeature(plane) ) { - if ( !pcActiveBody->isAfterInsertPoint ( plane ) ) { - validPlanes++; - status.push_back(PartDesignGui::TaskFeaturePick::validFeature); - } else { - status.push_back(PartDesignGui::TaskFeaturePick::afterTip); - } - } else { - PartDesign::Body *planeBody = PartDesign::Body::findBodyOf (plane); - if ( planeBody ) { - if ( ( geoGroup && geoGroup->hasObject ( planeBody, true ) ) || - !App::GeoFeatureGroup::getGroupOfObject (planeBody) ) { - status.push_back ( PartDesignGui::TaskFeaturePick::otherBody ); - } else { - status.push_back ( PartDesignGui::TaskFeaturePick::otherPart ); - } - } else { - if ( ( geoGroup && geoGroup->hasObject ( plane, true ) ) || - !App::GeoFeatureGroup::getGroupOfObject ( plane ) ) { - status.push_back ( PartDesignGui::TaskFeaturePick::otherPart ); - } else if (pcActiveBody) { - status.push_back ( PartDesignGui::TaskFeaturePick::notInBody ); - } else { // if we are outside a body count it as valid - validPlanes++; - status.push_back(PartDesignGui::TaskFeaturePick::validFeature); - } - } - } - } - - if (validPlanes == 0) { - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No valid planes in this document"), - QObject::tr("Please create a plane first or select a face to sketch on")); - return; - } - - auto accepter = [=](const std::vector& features) -> bool { - - if(features.empty()) - return false; - - return true; - }; - - auto worker = [=](const std::vector& features) { - App::Plane* plane = static_cast(features.front()); - std::string FeatName = getUniqueObjectName("Sketch"); - std::string supportString = std::string("(App.activeDocument().") + plane->getNameInDocument() + - ", [''])"; - - Gui::Command::openCommand("Create a new Sketch"); - Gui::Command::doCommand(Doc,"App.activeDocument().addObject('Sketcher::SketchObject','%s')",FeatName.c_str()); - Gui::Command::doCommand(Doc,"App.activeDocument().%s.Support = %s",FeatName.c_str(),supportString.c_str()); - Gui::Command::doCommand(Doc,"App.activeDocument().%s.MapMode = '%s'",FeatName.c_str(),Attacher::AttachEngine::eMapModeStrings[Attacher::mmFlatFace]); - Gui::Command::updateActive(); // Make sure the Support's Placement property is updated - Gui::Command::doCommand(Doc,"App.activeDocument().%s.addFeature(App.activeDocument().%s)", - pcActiveBody->getNameInDocument(), FeatName.c_str()); - //doCommand(Gui,"Gui.activeDocument().activeView().setCamera('%s')",cam.c_str()); - Gui::Command::doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); - }; - - // If there is more than one possibility, show dialog and let user pick plane - bool reversed = false; - if (validPlanes > 1) { - - Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog(); - PartDesignGui::TaskDlgFeaturePick *pickDlg = qobject_cast(dlg); - if (dlg && !pickDlg) { - QMessageBox msgBox; - msgBox.setText(QObject::tr("A dialog is already open in the task panel")); - msgBox.setInformativeText(QObject::tr("Do you want to close this dialog?")); - msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); - msgBox.setDefaultButton(QMessageBox::Yes); - int ret = msgBox.exec(); - if (ret == QMessageBox::Yes) - Gui::Control().closeDialog(); - else - return; - } - - if(dlg) - Gui::Control().closeDialog(); - - Gui::Selection().clearSelection(); - Gui::Control().showDialog(new PartDesignGui::TaskDlgFeaturePick(planes, status, accepter, worker)); - } - else { - worker(planes); - } - } -} - -bool CmdPartDesignNewSketch::isActive(void) -{ - if (getActiveGuiDocument()) - return true; - else - return false; -} - -//=========================================================================== -// Common utility functions for all features creating solids -//=========================================================================== - -void finishFeature(const Gui::Command* cmd, const std::string& FeatName, - App::DocumentObject* prevSolidFeature = nullptr, const bool hidePrevSolid = true) -{ - PartDesign::Body *pcActiveBody; - - if (prevSolidFeature) { - pcActiveBody = PartDesignGui::getBodyFor(prevSolidFeature, /*messageIfNot = */false); - } else { // insert into the same body as the given previous one - pcActiveBody = PartDesignGui::getBody(/*messageIfNot = */false); - } - - if (pcActiveBody) { - App::DocumentObject* lastSolidFeature = pcActiveBody->Tip.getValue(); - if (!prevSolidFeature || prevSolidFeature == lastSolidFeature) { - // If the previous feature not given or is the Tip add Feature after it. - cmd->doCommand(cmd->Doc,"App.activeDocument().%s.addFeature(App.activeDocument().%s)", - pcActiveBody->getNameInDocument(), FeatName.c_str()); - prevSolidFeature = lastSolidFeature; - } else { - // Insert the feature into the body after the given one. - cmd->doCommand(cmd->Doc, - "App.activeDocument().%s.insertFeature(App.activeDocument().%s, App.activeDocument().%s, True)", - pcActiveBody->getNameInDocument(), FeatName.c_str(), prevSolidFeature->getNameInDocument()); - } - } - - if (hidePrevSolid && prevSolidFeature && (prevSolidFeature != NULL)) - cmd->doCommand(cmd->Gui,"Gui.activeDocument().hide(\"%s\")", prevSolidFeature->getNameInDocument()); - - cmd->updateActive(); - // #0001721: use '0' as edit value to avoid switching off selection in - // ViewProviderGeometryObject::setEditViewer - cmd->doCommand(cmd->Gui,"Gui.activeDocument().setEdit('%s', 0)", FeatName.c_str()); - cmd->doCommand(cmd->Gui,"Gui.Selection.clearSelection()"); - //cmd->doCommand(cmd->Gui,"Gui.Selection.addSelection(App.ActiveDocument.ActiveObject)"); - - if (pcActiveBody) { - cmd->copyVisual(FeatName.c_str(), "ShapeColor", pcActiveBody->getNameInDocument()); - cmd->copyVisual(FeatName.c_str(), "LineColor", pcActiveBody->getNameInDocument()); - cmd->copyVisual(FeatName.c_str(), "PointColor", pcActiveBody->getNameInDocument()); - } -} - -//=========================================================================== -// Common utility functions for SketchBased features -//=========================================================================== - -// Take a list of Part2DObjects and erase those which are not eligible for creating a -// SketchBased feature. -const unsigned validateSketches(std::vector& sketches, - std::vector& status, - std::vector::iterator& firstValidSketch) -{ - // TODO Review the function for non-part bodies (2015-09-04, Fat-Zer) - PartDesign::Body* pcActiveBody = PartDesignGui::getBody(false); - App::Part* pcActivePart = PartDesignGui::getPartFor(pcActiveBody, false); - - // TODO: If the user previously opted to allow multiple use of sketches or use of sketches from other bodies, - // then count these as valid sketches! - unsigned validSketches = 0; - firstValidSketch = sketches.end(); - - for (std::vector::iterator s = sketches.begin(); s != sketches.end(); s++) { - - if (!pcActiveBody) { - // We work in the old style outside any body - if (PartDesign::Body::findBodyOf (*s)) { - status.push_back(PartDesignGui::TaskFeaturePick::otherPart); - ++validSketches; - continue; - } - } else if (!pcActiveBody->hasFeature(*s)) { - // Check whether this plane belongs to the active body - if(pcActivePart && pcActivePart->hasObject(*s, true)) { - status.push_back(PartDesignGui::TaskFeaturePick::otherBody); - } else if (PartDesign::Body::findBodyOf(*s)) { - status.push_back(PartDesignGui::TaskFeaturePick::otherPart); - } else { - status.push_back(PartDesignGui::TaskFeaturePick::notInBody); - } - - ++validSketches; - continue; - } - - //Base::Console().Error("Checking sketch %s\n", (*s)->getNameInDocument()); - // Check whether this sketch is already being used by another feature - // Body features don't count... - std::vector inList = (*s)->getInList(); - std::vector::iterator o = inList.begin(); - while (o != inList.end()) { - //Base::Console().Error("Inlist: %s\n", (*o)->getNameInDocument()); - if ((*o)->getTypeId().isDerivedFrom(PartDesign::Body::getClassTypeId())) - o = inList.erase(o); //ignore bodies - else if (!( (*o)->getTypeId().isDerivedFrom(PartDesign::Feature::getClassTypeId()) )) - o = inList.erase(o); //ignore non-partDesign - else - ++o; - } - if (inList.size() > 0) { - status.push_back(PartDesignGui::TaskFeaturePick::isUsed); - continue; - } - - if (pcActiveBody && pcActiveBody->isAfterInsertPoint(*s)){ - status.push_back(PartDesignGui::TaskFeaturePick::afterTip); - continue; - } - - // Check whether the sketch shape is valid - Part::Part2DObject* sketch = static_cast(*s); - const TopoDS_Shape& shape = sketch->Shape.getValue(); - if (shape.IsNull()) { - status.push_back(PartDesignGui::TaskFeaturePick::invalidShape); - continue; - } - - // count free wires - int ctWires=0; - TopExp_Explorer ex; - for (ex.Init(shape, TopAbs_WIRE); ex.More(); ex.Next()) { - ctWires++; - } - if (ctWires == 0) { - status.push_back(PartDesignGui::TaskFeaturePick::noWire); - continue; - } - - // All checks passed - found a valid sketch - if (firstValidSketch == sketches.end()) - firstValidSketch = s; - validSketches++; - status.push_back(PartDesignGui::TaskFeaturePick::validFeature); - } - - return validSketches; -} - -void prepareSketchBased(Gui::Command* cmd, const std::string& which, - boost::function func) -{ - bool bNoSketchWasSelected = false; - // Get a valid sketch from the user - // First check selections - std::vector sketches = cmd->getSelection().getObjectsOfType(Part::Part2DObject::getClassTypeId()); - if (sketches.size() == 0) {//no sketches were selected. Let user pick an object from valid ones available in document - sketches = cmd->getDocument()->getObjectsOfType(Part::Part2DObject::getClassTypeId()); - bNoSketchWasSelected = true; - } - std::vector status; - std::vector::iterator firstValidSketch; - unsigned validSketches = validateSketches(sketches, status, firstValidSketch); - if (validSketches == 0) { - if (bNoSketchWasSelected) { - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No sketch to work on"), - QObject::tr("No sketch was selected. None of the sketches in the document is free.")); - return; - } else { - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No valid sketches selected"), - QObject::tr("Attention: none of selected sketches/2D objects is free.")); - } - } - - auto accepter = [=](const std::vector& features) -> bool { - - if(features.empty()) - return false; - - return true; - }; - - auto worker = [which, cmd, func](std::vector features) { - - auto firstValidSketch = features.begin(); - Part::Part2DObject* sketch = static_cast(*firstValidSketch); - - std::string FeatName = cmd->getUniqueObjectName(which.c_str()); - - Gui::Command::openCommand((std::string("Make ") + which).c_str()); - Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().addObject(\"PartDesign::%s\",\"%s\")", - which.c_str(), FeatName.c_str()); - Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().%s.Sketch = App.activeDocument().%s", - FeatName.c_str(), sketch->getNameInDocument()); - - func(sketch, FeatName); - }; - - //if there is a sketch selected which is from annother body or part we need to bring up the - //pick task dialog to decide how those are handled - bool ext = std::find_if( status.begin(), status.end(), - [] (const PartDesignGui::TaskFeaturePick::featureStatus& s) { - return s == PartDesignGui::TaskFeaturePick::otherBody || - s == PartDesignGui::TaskFeaturePick::otherPart || - s == PartDesignGui::TaskFeaturePick::notInBody; - } - ) != status.end(); - // TODO Clean this up (2015-10-20, Fat-Zer) - auto* pcActiveBody = PartDesignGui::getBody(false); - if(pcActiveBody && !bNoSketchWasSelected && ext) { - - auto* pcActivePart = PartDesignGui::getPartFor(pcActiveBody, false); - - // TODO share this with UnifiedDatumCommand() (2015-10-20, Fat-Zer) - QDialog* dia = new QDialog; - Ui_Dialog dlg; - dlg.setupUi(dia); - dia->setModal(true); - int result = dia->exec(); - if(result == QDialog::DialogCode::Rejected) - return; - else if(!dlg.radioXRef->isChecked()) { - - auto copy = PartDesignGui::TaskFeaturePick::makeCopy(sketches[0], "", dlg.radioIndependent->isChecked()); - auto oBody = PartDesignGui::getBodyFor(sketches[0], false); - if(oBody) - pcActiveBody->addFeature(copy); - else - pcActivePart->addObject(copy); - - } - } - - // If there is more than one selection/possibility, show dialog and let user pick sketch - if ((bNoSketchWasSelected && validSketches > 1) || - (!bNoSketchWasSelected && sketches.size() > 1)) { - - Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog(); - PartDesignGui::TaskDlgFeaturePick *pickDlg = qobject_cast(dlg); - if (dlg && !pickDlg) { - QMessageBox msgBox; - msgBox.setText(QObject::tr("A dialog is already open in the task panel")); - msgBox.setInformativeText(QObject::tr("Do you want to close this dialog?")); - msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); - msgBox.setDefaultButton(QMessageBox::Yes); - int ret = msgBox.exec(); - if (ret == QMessageBox::Yes) - Gui::Control().closeDialog(); - else - return; - } - - if(dlg) - Gui::Control().closeDialog(); - - Gui::Selection().clearSelection(); - pickDlg = new PartDesignGui::TaskDlgFeaturePick(sketches, status, accepter, worker); - if(!bNoSketchWasSelected && ext) - pickDlg->showExternal(true); - - Gui::Control().showDialog(pickDlg); - } - else { - std::vector theSketch; - theSketch.reserve(1); - if (bNoSketchWasSelected && validSketches == 1){ - theSketch.push_back(*firstValidSketch); - } else if(!bNoSketchWasSelected && sketches.size() == 1) { - theSketch = sketches; - } - worker(theSketch); - } - -} - -void finishSketchBased(const Gui::Command* cmd, const Part::Part2DObject* sketch, const std::string& FeatName) -{ - cmd->doCommand(cmd->Gui,"Gui.activeDocument().hide(\"%s\")", sketch->getNameInDocument()); - finishFeature(cmd, FeatName); -} - -//=========================================================================== -// PartDesign_Pad -//=========================================================================== -DEF_STD_CMD_A(CmdPartDesignPad); - -CmdPartDesignPad::CmdPartDesignPad() - : Command("PartDesign_Pad") -{ - sAppModule = "PartDesign"; - sGroup = QT_TR_NOOP("PartDesign"); - sMenuText = QT_TR_NOOP("Pad"); - sToolTipText = QT_TR_NOOP("Pad a selected sketch"); - sWhatsThis = "PartDesign_Pad"; - sStatusTip = sToolTipText; - sPixmap = "PartDesign_Pad"; -} - -void CmdPartDesignPad::activated(int iMsg) -{ - Gui::Command* cmd = this; - auto worker = [cmd](Part::Part2DObject* sketch, std::string FeatName) { - - if (FeatName.empty()) return; - - // specific parameters for Pad - Gui::Command::doCommand(Doc,"App.activeDocument().%s.Length = 10.0",FeatName.c_str()); - App::DocumentObjectGroup* grp = sketch->getGroup(); - if (grp) { - Gui::Command::doCommand(Doc,"App.activeDocument().%s.addObject(App.activeDocument().%s)" - ,grp->getNameInDocument(),FeatName.c_str()); - Gui::Command::doCommand(Doc,"App.activeDocument().%s.removeObject(App.activeDocument().%s)" - ,grp->getNameInDocument(),sketch->getNameInDocument()); - } - Gui::Command::updateActive(); - - finishSketchBased(cmd, sketch, FeatName); - cmd->adjustCameraPosition(); - }; - - prepareSketchBased(this, "Pad", worker); -} - -bool CmdPartDesignPad::isActive(void) -{ - return hasActiveDocument(); -} - -//=========================================================================== -// PartDesign_Pocket -//=========================================================================== -DEF_STD_CMD_A(CmdPartDesignPocket); - -CmdPartDesignPocket::CmdPartDesignPocket() - : Command("PartDesign_Pocket") -{ - sAppModule = "PartDesign"; - sGroup = QT_TR_NOOP("PartDesign"); - sMenuText = QT_TR_NOOP("Pocket"); -<<<<<<< 2bec9f6b8861913cb54dcf56f00481324deabda8 - sToolTipText = QT_TR_NOOP("Create a pocket with the selected sketch"); - sWhatsThis = "PartDesign_Pocket"; -======= - sToolTipText = QT_TR_NOOP("create a pocket with the selected sketch"); - sWhatsThis = sToolTipText; ->>>>>>> ask user if he creates inter part/body references - sStatusTip = sToolTipText; - sPixmap = "PartDesign_Pocket"; -} - -void CmdPartDesignPocket::activated(int iMsg) -{ - Gui::Command* cmd = this; - auto worker = [cmd](Part::Part2DObject* sketch, std::string FeatName) { - - if (FeatName.empty()) return; - - Gui::Command::doCommand(Doc,"App.activeDocument().%s.Length = 5.0",FeatName.c_str()); - finishSketchBased(cmd, sketch, FeatName); - cmd->adjustCameraPosition(); - }; - - prepareSketchBased(this, "Pocket", worker); -} - -bool CmdPartDesignPocket::isActive(void) -{ - return hasActiveDocument(); -} - -//=========================================================================== -// PartDesign_Revolution -//=========================================================================== -DEF_STD_CMD_A(CmdPartDesignRevolution); - -CmdPartDesignRevolution::CmdPartDesignRevolution() - : Command("PartDesign_Revolution") -{ - sAppModule = "PartDesign"; - sGroup = QT_TR_NOOP("PartDesign"); - sMenuText = QT_TR_NOOP("Revolution"); - sToolTipText = QT_TR_NOOP("Revolve a selected sketch"); - sWhatsThis = "PartDesign_Revolution"; - sStatusTip = sToolTipText; - sPixmap = "PartDesign_Revolution"; -} - -void CmdPartDesignRevolution::activated(int iMsg) -{ - Gui::Command* cmd = this; - auto worker = [cmd](Part::Part2DObject* sketch, std::string FeatName) { - - if (FeatName.empty()) return; - - Gui::Command::doCommand(Doc,"App.activeDocument().%s.ReferenceAxis = (App.activeDocument().%s,['V_Axis'])", - FeatName.c_str(), sketch->getNameInDocument()); - Gui::Command::doCommand(Doc,"App.activeDocument().%s.Angle = 360.0",FeatName.c_str()); - PartDesign::Revolution* pcRevolution = static_cast(cmd->getDocument()->getObject(FeatName.c_str())); - if (pcRevolution && pcRevolution->suggestReversed()) - Gui::Command::doCommand(Doc,"App.activeDocument().%s.Reversed = 1",FeatName.c_str()); - - finishSketchBased(cmd, sketch, FeatName); - cmd->adjustCameraPosition(); - }; - - prepareSketchBased(this, "Revolution", worker); -} - -bool CmdPartDesignRevolution::isActive(void) -{ - return hasActiveDocument(); -} - -//=========================================================================== -// PartDesign_Groove -//=========================================================================== -DEF_STD_CMD_A(CmdPartDesignGroove); - -CmdPartDesignGroove::CmdPartDesignGroove() - : Command("PartDesign_Groove") -{ - sAppModule = "PartDesign"; - sGroup = QT_TR_NOOP("PartDesign"); - sMenuText = QT_TR_NOOP("Groove"); - sToolTipText = QT_TR_NOOP("Groove a selected sketch"); - sWhatsThis = "PartDesign_Groove"; - sStatusTip = sToolTipText; - sPixmap = "PartDesign_Groove"; -} - -void CmdPartDesignGroove::activated(int iMsg) -{ - Gui::Command* cmd = this; - auto worker = [cmd](Part::Part2DObject* sketch, std::string FeatName) { - - if (FeatName.empty()) return; - - Gui::Command::doCommand(Doc,"App.activeDocument().%s.ReferenceAxis = (App.activeDocument().%s,['V_Axis'])", - FeatName.c_str(), sketch->getNameInDocument()); - Gui::Command::doCommand(Doc,"App.activeDocument().%s.Angle = 360.0",FeatName.c_str()); - PartDesign::Groove* pcGroove = static_cast(cmd->getDocument()->getObject(FeatName.c_str())); - if (pcGroove && pcGroove->suggestReversed()) - Gui::Command::doCommand(Doc,"App.activeDocument().%s.Reversed = 1",FeatName.c_str()); - - finishSketchBased(cmd, sketch, FeatName); - cmd->adjustCameraPosition(); - }; - - prepareSketchBased(this, "Groove", worker); -} - -bool CmdPartDesignGroove::isActive(void) -{ - return hasActiveDocument(); -} - -//=========================================================================== -// PartDesign_Additive_Pipe -//=========================================================================== -DEF_STD_CMD_A(CmdPartDesignAdditivePipe); - -CmdPartDesignAdditivePipe::CmdPartDesignAdditivePipe() - : Command("PartDesign_AdditivePipe") -{ - sAppModule = "PartDesign"; - sGroup = QT_TR_NOOP("PartDesign"); - sMenuText = QT_TR_NOOP("Additive pipe"); - sToolTipText = QT_TR_NOOP("Sweep a selected sketch along a path or to other profiles"); - sWhatsThis = "PartDesign_Additive_Pipe"; - sStatusTip = sToolTipText; - sPixmap = "PartDesign_Additive_Pipe"; -} - -void CmdPartDesignAdditivePipe::activated(int iMsg) -{ - Gui::Command* cmd = this; - auto worker = [cmd](Part::Part2DObject* sketch, std::string FeatName) { - - if (FeatName.empty()) return; - - // specific parameters for pipe - Gui::Command::updateActive(); - - finishSketchBased(cmd, sketch, FeatName); - cmd->adjustCameraPosition(); - }; - - prepareSketchBased(this, "AdditivePipe", worker); -} - -bool CmdPartDesignAdditivePipe::isActive(void) -{ - return hasActiveDocument(); -} - - -//=========================================================================== -// PartDesign_Subtractive_Pipe -//=========================================================================== -DEF_STD_CMD_A(CmdPartDesignSubtractivePipe); - -CmdPartDesignSubtractivePipe::CmdPartDesignSubtractivePipe() - : Command("PartDesign_SubtractivePipe") -{ - sAppModule = "PartDesign"; - sGroup = QT_TR_NOOP("PartDesign"); - sMenuText = QT_TR_NOOP("Subtractive pipe"); - sToolTipText = QT_TR_NOOP("Sweep a selected sketch along a path or to other profiles and remove it from the body"); - sWhatsThis = "PartDesign_Subtractive_Pipe"; - sStatusTip = sToolTipText; - sPixmap = "PartDesign_Subtractive_Pipe"; -} - -void CmdPartDesignSubtractivePipe::activated(int iMsg) -{ - Gui::Command* cmd = this; - auto worker = [cmd](Part::Part2DObject* sketch, std::string FeatName) { - - if (FeatName.empty()) return; - - // specific parameters for pipe - Gui::Command::updateActive(); - - finishSketchBased(cmd, sketch, FeatName); - cmd->adjustCameraPosition(); - }; - - prepareSketchBased(this, "SubtractivePipe", worker); -} - -bool CmdPartDesignSubtractivePipe::isActive(void) -{ - return hasActiveDocument(); -} - - -//=========================================================================== -// PartDesign_Additive_Loft -//=========================================================================== -DEF_STD_CMD_A(CmdPartDesignAdditiveLoft); - -CmdPartDesignAdditiveLoft::CmdPartDesignAdditiveLoft() - : Command("PartDesign_AdditiveLoft") -{ - sAppModule = "PartDesign"; - sGroup = QT_TR_NOOP("PartDesign"); - sMenuText = QT_TR_NOOP("Additive loft"); - sToolTipText = QT_TR_NOOP("Sweep a selected sketch along a path or to other profiles"); - sWhatsThis = "PartDesign_Additive_Loft"; - sStatusTip = sToolTipText; - sPixmap = "PartDesign_Additive_Loft"; -} - -void CmdPartDesignAdditiveLoft::activated(int iMsg) -{ - Gui::Command* cmd = this; - auto worker = [cmd](Part::Part2DObject* sketch, std::string FeatName) { - - if (FeatName.empty()) return; - - // specific parameters for pipe - Gui::Command::updateActive(); - - finishSketchBased(cmd, sketch, FeatName); - cmd->adjustCameraPosition(); - }; - - prepareSketchBased(this, "AdditiveLoft", worker); -} - -bool CmdPartDesignAdditiveLoft::isActive(void) -{ - return hasActiveDocument(); -} - - -//=========================================================================== -// PartDesign_Subtractive_Loft -//=========================================================================== -DEF_STD_CMD_A(CmdPartDesignSubtractiveLoft); - -CmdPartDesignSubtractiveLoft::CmdPartDesignSubtractiveLoft() - : Command("PartDesign_SubtractiveLoft") -{ - sAppModule = "PartDesign"; - sGroup = QT_TR_NOOP("PartDesign"); - sMenuText = QT_TR_NOOP("Subtractive loft"); - sToolTipText = QT_TR_NOOP("Sweep a selected sketch along a path or to other profiles and remove it from the body"); - sWhatsThis = "PartDesign_Subtractive_Loft"; - sStatusTip = sToolTipText; - sPixmap = "PartDesign_Subtractive_Loft"; -} - -void CmdPartDesignSubtractiveLoft::activated(int iMsg) -{ - Gui::Command* cmd = this; - auto worker = [cmd](Part::Part2DObject* sketch, std::string FeatName) { - - if (FeatName.empty()) return; - - // specific parameters for pipe - Gui::Command::updateActive(); - - finishSketchBased(cmd, sketch, FeatName); - cmd->adjustCameraPosition(); - }; - - prepareSketchBased(this, "SubtractiveLoft", worker); -} - -bool CmdPartDesignSubtractiveLoft::isActive(void) -{ - return hasActiveDocument(); -} - -//=========================================================================== -// Common utility functions for Dressup features -//=========================================================================== - -bool dressupGetSelected(Gui::Command* cmd, const std::string& which, - Gui::SelectionObject &selected) -{ - std::vector selection = cmd->getSelection().getSelectionEx(); - selection = cmd->getSelection().getSelectionEx(); - - if (selection.size() == 0) { - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), - QObject::tr("Select an edge, face or body.")); - return false; - } else if (selection.size() != 1) { - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), - QObject::tr("Select an edge, face or body from a single body.")); - return false; - } - - Gui::Selection().clearSelection(); - - // set the - selected = selection[0]; - - if (!selected.isObjectTypeOf(Part::Feature::getClassTypeId())) { - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong object type"), - QObject::tr("%1 works only on parts.").arg(QString::fromStdString(which))); - return false; - } - - Part::Feature *base = static_cast(selected.getObject()); - - const Part::TopoShape& TopShape = base->Shape.getShape(); - - if (TopShape._Shape.IsNull()){ - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), - QObject::tr("Shape of the selected Part is empty")); - return false; - } - - return true; -} - -void finishDressupFeature(const Gui::Command* cmd, const std::string& which, - Part::Feature *base, const std::vector & SubNames) -{ - if (SubNames.size() == 0) { - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), - QString::fromStdString(which) + QObject::tr(" not possible on selected faces/edges.")); - return; - } - - std::string SelString; - SelString += "(App."; - SelString += "ActiveDocument"; - SelString += "."; - SelString += base->getNameInDocument(); - SelString += ",["; - for(std::vector::const_iterator it = SubNames.begin();it!=SubNames.end();++it){ - SelString += "\""; - SelString += *it; - SelString += "\""; - if(it != --SubNames.end()) - SelString += ","; - } - SelString += "])"; - - std::string FeatName = cmd->getUniqueObjectName(which.c_str()); - - cmd->openCommand((std::string("Make ") + which).c_str()); - cmd->doCommand(cmd->Doc,"App.activeDocument().addObject(\"PartDesign::%s\",\"%s\")",which.c_str(), FeatName.c_str()); - cmd->doCommand(cmd->Doc,"App.activeDocument().%s.Base = %s",FeatName.c_str(),SelString.c_str()); - doCommand(Gui,"Gui.Selection.clearSelection()"); - finishFeature(cmd, FeatName, base); -} - -void makeChamferOrFillet(Gui::Command* cmd, const std::string& which) -{ - Gui::SelectionObject selected; - if (!dressupGetSelected ( cmd, which, selected)) - return; - - Part::Feature *base = static_cast(selected.getObject()); - - std::vector SubNames = std::vector(selected.getSubNames()); - - finishDressupFeature (cmd, which, base, SubNames); -} - -//=========================================================================== -// PartDesign_Fillet -//=========================================================================== -DEF_STD_CMD_A(CmdPartDesignFillet); - -CmdPartDesignFillet::CmdPartDesignFillet() - :Command("PartDesign_Fillet") -{ - sAppModule = "PartDesign"; - sGroup = QT_TR_NOOP("PartDesign"); - sMenuText = QT_TR_NOOP("Fillet"); - sToolTipText = QT_TR_NOOP("Make a fillet on an edge, face or body"); - sWhatsThis = "PartDesign_Fillet"; - sStatusTip = sToolTipText; - sPixmap = "PartDesign_Fillet"; -} - -void CmdPartDesignFillet::activated(int iMsg) -{ - makeChamferOrFillet(this, "Fillet"); -} - -bool CmdPartDesignFillet::isActive(void) -{ - return hasActiveDocument(); -} - -//=========================================================================== -// PartDesign_Chamfer -//=========================================================================== -DEF_STD_CMD_A(CmdPartDesignChamfer); - -CmdPartDesignChamfer::CmdPartDesignChamfer() - :Command("PartDesign_Chamfer") -{ - sAppModule = "PartDesign"; - sGroup = QT_TR_NOOP("PartDesign"); - sMenuText = QT_TR_NOOP("Chamfer"); - sToolTipText = QT_TR_NOOP("Chamfer the selected edges of a shape"); - sWhatsThis = "PartDesign_Chamfer"; - sStatusTip = sToolTipText; - sPixmap = "PartDesign_Chamfer"; -} - -void CmdPartDesignChamfer::activated(int iMsg) -{ - makeChamferOrFillet(this, "Chamfer"); - doCommand(Gui,"Gui.Selection.clearSelection()"); -} - -bool CmdPartDesignChamfer::isActive(void) -{ - return hasActiveDocument(); -} - -//=========================================================================== -// PartDesign_Draft -//=========================================================================== -DEF_STD_CMD_A(CmdPartDesignDraft); - -CmdPartDesignDraft::CmdPartDesignDraft() - :Command("PartDesign_Draft") -{ - sAppModule = "PartDesign"; - sGroup = QT_TR_NOOP("PartDesign"); - sMenuText = QT_TR_NOOP("Draft"); - sToolTipText = QT_TR_NOOP("Make a draft on a face"); - sWhatsThis = "PartDesign_Draft"; - sStatusTip = sToolTipText; - sPixmap = "PartDesign_Draft"; -} - -void CmdPartDesignDraft::activated(int iMsg) -{ - Gui::SelectionObject selected; - if (!dressupGetSelected ( this, "Draft", selected)) - return; - - Part::Feature *base = static_cast(selected.getObject()); - std::vector SubNames = std::vector(selected.getSubNames()); - const Part::TopoShape& TopShape = base->Shape.getShape(); - size_t i = 0; - - // filter out the edges - while(i < SubNames.size()) - { - std::string aSubName = static_cast(SubNames.at(i)); - - if(aSubName.size() > 4 && aSubName.substr(0,4) == "Face") { - // Check for valid face types - TopoDS_Face face = TopoDS::Face(TopShape.getSubShape(aSubName.c_str())); - BRepAdaptor_Surface sf(face); - if ((sf.GetType() != GeomAbs_Plane) && (sf.GetType() != GeomAbs_Cylinder) && (sf.GetType() != GeomAbs_Cone)) - SubNames.erase(SubNames.begin()+i); - } else { - // empty name or any other sub-element - SubNames.erase(SubNames.begin()+i); - } - - i++; - } - - finishDressupFeature (this, "Draft", base, SubNames); -} - -bool CmdPartDesignDraft::isActive(void) -{ - return hasActiveDocument(); -} - - -//=========================================================================== -// PartDesign_Thickness -//=========================================================================== -DEF_STD_CMD_A(CmdPartDesignThickness); - -CmdPartDesignThickness::CmdPartDesignThickness() - :Command("PartDesign_Thickness") -{ - sAppModule = "PartDesign"; - sGroup = QT_TR_NOOP("PartDesign"); - sMenuText = QT_TR_NOOP("Thickness"); - sToolTipText = QT_TR_NOOP("Make a thick solid"); - sWhatsThis = "PartDesign_Thickness"; - sStatusTip = sToolTipText; - sPixmap = "PartDesign_Thickness"; -} - -void CmdPartDesignThickness::activated(int iMsg) -{ - Gui::SelectionObject selected; - if (!dressupGetSelected ( this, "Thickness", selected)) - return; - - Part::Feature *base = static_cast(selected.getObject()); - std::vector SubNames = std::vector(selected.getSubNames()); - size_t i = 0; - - // filter out the edges - while(i < SubNames.size()) - { - std::string aSubName = static_cast(SubNames.at(i)); - - if(aSubName.size() > 4 && aSubName.substr(0,4) != "Face") { - // empty name or any other sub-element - SubNames.erase(SubNames.begin()+i); - } - i++; - } - - finishDressupFeature (this, "Thickness", base, SubNames); -} - -bool CmdPartDesignThickness::isActive(void) -{ - return hasActiveDocument(); -} - -//=========================================================================== -// Common functions for all Transformed features -//=========================================================================== - -void prepareTransformed(Gui::Command* cmd, const std::string& which, - boost::function)> func) -{ - std::string FeatName = cmd->getUniqueObjectName(which.c_str()); - - auto accepter = [=](std::vector features) -> bool{ - - if(features.empty()) - return false; - - return true; - }; - - auto worker = [=](std::vector features) { - std::stringstream str; - str << "App.activeDocument()." << FeatName << ".Originals = ["; - for (std::vector::iterator it = features.begin(); it != features.end(); ++it){ - str << "App.activeDocument()." << (*it)->getNameInDocument() << ","; - } - str << "]"; - - Gui::Command::openCommand((std::string("Make ") + which + " feature").c_str()); - Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().addObject(\"PartDesign::%s\",\"%s\")",which.c_str(), FeatName.c_str()); - // FIXME: There seems to be kind of a race condition here, leading to sporadic errors like - // Exception (Thu Sep 6 11:52:01 2012): 'App.Document' object has no attribute 'Mirrored' - Gui::Command::updateActive(); // Helps to ensure that the object already exists when the next command comes up - Gui::Command::doCommand(Gui::Command::Doc, str.str().c_str()); - // TODO Wjat that function supposed to do? (2015-08-05, Fat-Zer) - func(FeatName, features); - }; - - // Get a valid original from the user - // First check selections - std::vector features = cmd->getSelection().getObjectsOfType(PartDesign::FeatureAddSub::getClassTypeId()); - // Next create a list of all eligible objects - if (features.size() == 0) { - features = cmd->getDocument()->getObjectsOfType(PartDesign::FeatureAddSub::getClassTypeId()); - // If there is more than one selected or eligible object, show dialog and let user pick one - if (features.size() > 1) { - std::vector status; - for (unsigned i = 0; i < features.size(); i++) - status.push_back(PartDesignGui::TaskFeaturePick::validFeature); - - Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog(); - PartDesignGui::TaskDlgFeaturePick *pickDlg = qobject_cast(dlg); - if (dlg && !pickDlg) { - QMessageBox msgBox; - msgBox.setText(QObject::tr("A dialog is already open in the task panel")); - msgBox.setInformativeText(QObject::tr("Do you want to close this dialog?")); - msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); - msgBox.setDefaultButton(QMessageBox::Yes); - int ret = msgBox.exec(); - if (ret == QMessageBox::Yes) - Gui::Control().closeDialog(); - else - return; - } - - if(dlg) - Gui::Control().closeDialog(); - - Gui::Selection().clearSelection(); - Gui::Control().showDialog(new PartDesignGui::TaskDlgFeaturePick(features, status, accepter, worker)); - } else { - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No valid features in this document"), - QObject::tr("Please create a subtractive or additive feature first.")); - return; - } - } - else { - worker(features); - } -} - -void finishTransformed(Gui::Command* cmd, std::string& FeatName) -{ - finishFeature(cmd, FeatName); -} - -//=========================================================================== -// PartDesign_Mirrored -//=========================================================================== -DEF_STD_CMD_A(CmdPartDesignMirrored); - -CmdPartDesignMirrored::CmdPartDesignMirrored() - : Command("PartDesign_Mirrored") -{ - sAppModule = "PartDesign"; - sGroup = QT_TR_NOOP("PartDesign"); - sMenuText = QT_TR_NOOP("Mirrored"); - sToolTipText = QT_TR_NOOP("create a mirrored feature"); - sWhatsThis = "PartDesign_Mirrored"; - sStatusTip = sToolTipText; - sPixmap = "PartDesign_Mirrored"; -} - -void CmdPartDesignMirrored::activated(int iMsg) -{ - Gui::Command* cmd = this; - auto worker = [cmd](std::string FeatName, std::vector features) { - - if (features.empty()) - return; - - if(features.front()->isDerivedFrom(PartDesign::SketchBased::getClassTypeId())) { - Part::Part2DObject *sketch = (static_cast(features.front()))->getVerifiedSketch(/* silent =*/ true); - if (sketch) - Gui::Command::doCommand(Doc,"App.activeDocument().%s.MirrorPlane = (App.activeDocument().%s, [\"V_Axis\"])", - FeatName.c_str(), sketch->getNameInDocument()); - } - // TODO Check if default mirrored plane correctly set (2015-09-01, Fat-Zer) - // else { - // doCommand(Doc,"App.activeDocument().%s.MirrorPlane = (App.activeDocument().%s, [\"\"])", FeatName.c_str(), - // App::Part::BaseplaneTypes[0]); - // } - - finishTransformed(cmd, FeatName); - }; - - prepareTransformed(this, "Mirrored", worker); -} - -bool CmdPartDesignMirrored::isActive(void) -{ - return hasActiveDocument(); -} - -//=========================================================================== -// PartDesign_LinearPattern -//=========================================================================== -DEF_STD_CMD_A(CmdPartDesignLinearPattern); - -CmdPartDesignLinearPattern::CmdPartDesignLinearPattern() - : Command("PartDesign_LinearPattern") -{ - sAppModule = "PartDesign"; - sGroup = QT_TR_NOOP("PartDesign"); - sMenuText = QT_TR_NOOP("LinearPattern"); - sToolTipText = QT_TR_NOOP("Create a linear pattern feature"); - sWhatsThis = "PartDesign_LinearPattern"; - sStatusTip = sToolTipText; - sPixmap = "PartDesign_LinearPattern"; -} - -void CmdPartDesignLinearPattern::activated(int iMsg) -{ - Gui::Command* cmd = this; - auto worker = [cmd](std::string FeatName, std::vector features) { - - if (features.empty()) - return; - - if(features.front()->isDerivedFrom(PartDesign::SketchBased::getClassTypeId())) { - Part::Part2DObject *sketch = (static_cast(features.front()))->getVerifiedSketch(/* silent =*/ true); - if (sketch) - doCommand(Doc,"App.activeDocument().%s.Direction = (App.activeDocument().%s, [\"H_Axis\"])", - FeatName.c_str(), sketch->getNameInDocument()); - } - // TODO Check if default direction correctly set (2015-09-01, Fat-Zer) - // else { - // doCommand(Doc,"App.activeDocument().%s.Direction = (App.activeDocument().%s, [\"\"])", FeatName.c_str(), - // App::Part::BaselineTypes[0]); - // } - doCommand(Doc,"App.activeDocument().%s.Length = 100", FeatName.c_str()); - doCommand(Doc,"App.activeDocument().%s.Occurrences = 2", FeatName.c_str()); - - finishTransformed(cmd, FeatName); - }; - - prepareTransformed(this, "LinearPattern", worker); -} - -bool CmdPartDesignLinearPattern::isActive(void) -{ - return hasActiveDocument(); -} - -//=========================================================================== -// PartDesign_PolarPattern -//=========================================================================== -DEF_STD_CMD_A(CmdPartDesignPolarPattern); - -CmdPartDesignPolarPattern::CmdPartDesignPolarPattern() - : Command("PartDesign_PolarPattern") -{ - sAppModule = "PartDesign"; - sGroup = QT_TR_NOOP("PartDesign"); - sMenuText = QT_TR_NOOP("PolarPattern"); - sToolTipText = QT_TR_NOOP("Create a polar pattern feature"); - sWhatsThis = "PartDesign_PolarPattern"; - sStatusTip = sToolTipText; - sPixmap = "PartDesign_PolarPattern"; -} - -void CmdPartDesignPolarPattern::activated(int iMsg) -{ - Gui::Command* cmd = this; - auto worker = [cmd](std::string FeatName, std::vector features) { - - if (features.empty()) - return; - - if(features.front()->isDerivedFrom(PartDesign::SketchBased::getClassTypeId())) { - Part::Part2DObject *sketch = (static_cast(features.front()))->getVerifiedSketch(/* silent =*/ true); - if (sketch) - doCommand(Doc,"App.activeDocument().%s.Axis = (App.activeDocument().%s, [\"N_Axis\"])", - FeatName.c_str(), sketch->getNameInDocument()); - } - // TODO Check if default axis correctly set (2015-09-01, Fat-Zer) - // else { - // doCommand(Doc,"App.activeDocument().%s.Axis = (App.activeDocument().%s, [\"\"])", FeatName.c_str(), - // App::Part::BaselineTypes[0]); - // } - - doCommand(Doc,"App.activeDocument().%s.Angle = 360", FeatName.c_str()); - doCommand(Doc,"App.activeDocument().%s.Occurrences = 2", FeatName.c_str()); - - finishTransformed(cmd, FeatName); - }; - - prepareTransformed(this, "PolarPattern", worker); -} - -bool CmdPartDesignPolarPattern::isActive(void) -{ - return hasActiveDocument(); -} - -//=========================================================================== -// PartDesign_Scaled -//=========================================================================== -DEF_STD_CMD_A(CmdPartDesignScaled); - -CmdPartDesignScaled::CmdPartDesignScaled() - : Command("PartDesign_Scaled") -{ - sAppModule = "PartDesign"; - sGroup = QT_TR_NOOP("PartDesign"); - sMenuText = QT_TR_NOOP("Scaled"); - sToolTipText = QT_TR_NOOP("Create a scaled feature"); - sWhatsThis = "PartDesign_Scaled"; - sStatusTip = sToolTipText; - sPixmap = "PartDesign_Scaled"; -} - -void CmdPartDesignScaled::activated(int iMsg) -{ - Gui::Command* cmd = this; - auto worker = [cmd](std::string FeatName, std::vector features) { - - if (features.empty()) - return; - - doCommand(Doc,"App.activeDocument().%s.Factor = 2", FeatName.c_str()); - doCommand(Doc,"App.activeDocument().%s.Occurrences = 2", FeatName.c_str()); - - finishTransformed(cmd, FeatName); - }; - - prepareTransformed(this, "Scaled", worker); -} - -bool CmdPartDesignScaled::isActive(void) -{ - return hasActiveDocument(); -} - -//=========================================================================== -// PartDesign_MultiTransform -//=========================================================================== -DEF_STD_CMD_A(CmdPartDesignMultiTransform); - -CmdPartDesignMultiTransform::CmdPartDesignMultiTransform() - : Command("PartDesign_MultiTransform") -{ - sAppModule = "PartDesign"; - sGroup = QT_TR_NOOP("PartDesign"); - sMenuText = QT_TR_NOOP("Create MultiTransform"); - sToolTipText = QT_TR_NOOP("Create a multitransform feature"); - sWhatsThis = "PartDesign_MultiTransform"; - sStatusTip = sToolTipText; - sPixmap = "PartDesign_MultiTransform"; -} - -void CmdPartDesignMultiTransform::activated(int iMsg) -{ - PartDesign::Body *pcActiveBody = PartDesignGui::getBody(/*messageIfNot = */false); - //if (!pcActiveBody) return; - - std::vector features; - - // Check if a Transformed feature has been selected, convert it to MultiTransform - features = getSelection().getObjectsOfType(PartDesign::Transformed::getClassTypeId()); - if (!features.empty()) { - // Throw out MultiTransform features, we don't want to nest them - for (std::vector::iterator f = features.begin(); f != features.end(); ) { - if ((*f)->getTypeId().isDerivedFrom(PartDesign::MultiTransform::getClassTypeId())) - f = features.erase(f); - else - f++; - } - - if (features.empty()) return; - // Note: If multiple Transformed features were selected, only the first one is used - PartDesign::Transformed* trFeat = static_cast(features.front()); - - // Move the insert point back one feature - App::DocumentObject* oldTip = 0; - App::DocumentObject* prevFeature = 0; - if (pcActiveBody){ - oldTip = pcActiveBody->Tip.getValue(); - prevFeature = pcActiveBody->getPrevFeature(trFeat); - } - Gui::Selection().clearSelection(); - if (prevFeature != NULL) - Gui::Selection().addSelection(prevFeature->getDocument()->getName(), prevFeature->getNameInDocument()); - // TODO Review this (2015-09-05, Fat-Zer) - openCommand("Convert to MultiTransform feature"); - doCommand(Gui, "FreeCADGui.runCommand('PartDesign_MoveTip')"); - - // Remove the Transformed feature from the Body - if(pcActiveBody) - doCommand(Doc, "App.activeDocument().%s.removeFeature(App.activeDocument().%s)", - pcActiveBody->getNameInDocument(), trFeat->getNameInDocument()); - - // Create a MultiTransform feature and move the Transformed feature inside it - std::string FeatName = getUniqueObjectName("MultiTransform"); - doCommand(Doc, "App.activeDocument().addObject(\"PartDesign::MultiTransform\",\"%s\")", FeatName.c_str()); - doCommand(Doc, "App.activeDocument().%s.Originals = App.activeDocument().%s.Originals", FeatName.c_str(), trFeat->getNameInDocument()); - doCommand(Doc, "App.activeDocument().%s.Originals = []", trFeat->getNameInDocument()); - doCommand(Doc, "App.activeDocument().%s.Transformations = [App.activeDocument().%s]", FeatName.c_str(), trFeat->getNameInDocument()); - - // Add the MultiTransform into the Body at the current insert point - finishFeature(this, FeatName); - - // Restore the insert point - if (pcActiveBody && oldTip != trFeat) { - Gui::Selection().clearSelection(); - Gui::Selection().addSelection(oldTip->getDocument()->getName(), oldTip->getNameInDocument()); - Gui::Command::doCommand(Gui::Command::Gui,"FreeCADGui.runCommand('PartDesign_MoveTip')"); - Gui::Selection().clearSelection(); - } // otherwise the insert point remains at the new MultiTransform, which is fine - } else { - - Gui::Command* cmd = this; - auto worker = [cmd, pcActiveBody](std::string FeatName, std::vector features) { - - if (features.empty()) - return; - - // Make sure the user isn't presented with an empty screen because no transformations are defined yet... - App::DocumentObject* prevSolid = pcActiveBody->Tip.getValue(); - if (prevSolid != NULL) { - Part::Feature* feat = static_cast(prevSolid); - doCommand(Doc,"App.activeDocument().%s.Shape = App.activeDocument().%s.Shape", - FeatName.c_str(), feat->getNameInDocument()); - } - finishFeature(cmd, FeatName); - }; - - prepareTransformed(this, "MultiTransform", worker); - } -} - -bool CmdPartDesignMultiTransform::isActive(void) -{ - return hasActiveDocument(); -} - -//=========================================================================== -// PartDesign_Boolean -//=========================================================================== - -/* Boolean commands =======================================================*/ -DEF_STD_CMD_A(CmdPartDesignBoolean); - -CmdPartDesignBoolean::CmdPartDesignBoolean() - :Command("PartDesign_Boolean") -{ - sAppModule = "PartDesign"; - sGroup = QT_TR_NOOP("PartDesign"); - sMenuText = QT_TR_NOOP("Boolean operation"); - sToolTipText = QT_TR_NOOP("Boolean operation with two or more bodies"); - sWhatsThis = sToolTipText; - sStatusTip = sToolTipText; - sPixmap = "PartDesign_Boolean"; -} - - -void CmdPartDesignBoolean::activated(int iMsg) -{ - Gui::SelectionFilter BodyFilter("SELECT PartDesign::Body COUNT 1.."); - PartDesign::Body* body; - std::string bodyString(""); - - if (BodyFilter.match()) { - body = static_cast(BodyFilter.Result[0][0].getObject()); - std::vector bodies; - std::vector >::iterator i = BodyFilter.Result.begin(); - i++; - for (; i != BodyFilter.Result.end(); i++) { - for (std::vector::iterator j = i->begin(); j != i->end(); j++) { - bodies.push_back(j->getObject()); - } - } - bodyString = PartDesignGui::buildLinkListPythonStr(bodies); - } else { - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No body selected"), - QObject::tr("Please select a body for the boolean operation")); - return; - } - - openCommand("Create Boolean"); - - PartDesign::Body* activeBody = Gui::Application::Instance->activeView()->getActiveObject(PDBODYKEY); - // Make sure we are working on the selected body - if (body != activeBody) { - Gui::Selection().clearSelection(); - Gui::Selection().addSelection(body->getDocument()->getName(), body->Tip.getValue()->getNameInDocument()); - Gui::Command::doCommand(Gui::Command::Gui,"FreeCADGui.runCommand('PartDesign_MoveTip')"); - } - - std::string FeatName = getUniqueObjectName("Boolean"); - - doCommand(Doc,"App.activeDocument().addObject('PartDesign::Boolean','%s')",FeatName.c_str()); - if (!bodyString.empty()) - doCommand(Doc,"App.activeDocument().%s.Bodies = %s",FeatName.c_str(),bodyString.c_str()); - finishFeature(this, FeatName, nullptr, false); -} - -bool CmdPartDesignBoolean::isActive(void) -{ - if (getActiveGuiDocument()) - return true; - else - return false; -} - - -//=========================================================================== -// Initialization -//=========================================================================== - -void CreatePartDesignCommands(void) -{ - Gui::CommandManager &rcCmdMgr = Gui::Application::Instance->commandManager(); - - rcCmdMgr.addCommand(new CmdPartDesignShapeBinder()); - rcCmdMgr.addCommand(new CmdPartDesignPlane()); - rcCmdMgr.addCommand(new CmdPartDesignLine()); - rcCmdMgr.addCommand(new CmdPartDesignPoint()); - - rcCmdMgr.addCommand(new CmdPartDesignNewSketch()); - - rcCmdMgr.addCommand(new CmdPartDesignPad()); - rcCmdMgr.addCommand(new CmdPartDesignPocket()); - rcCmdMgr.addCommand(new CmdPartDesignRevolution()); - rcCmdMgr.addCommand(new CmdPartDesignGroove()); - rcCmdMgr.addCommand(new CmdPartDesignAdditivePipe); - rcCmdMgr.addCommand(new CmdPartDesignSubtractivePipe); - rcCmdMgr.addCommand(new CmdPartDesignAdditiveLoft); - rcCmdMgr.addCommand(new CmdPartDesignSubtractiveLoft); - - rcCmdMgr.addCommand(new CmdPartDesignFillet()); - rcCmdMgr.addCommand(new CmdPartDesignDraft()); - rcCmdMgr.addCommand(new CmdPartDesignChamfer()); - rcCmdMgr.addCommand(new CmdPartDesignThickness()); - - rcCmdMgr.addCommand(new CmdPartDesignMirrored()); - rcCmdMgr.addCommand(new CmdPartDesignLinearPattern()); - rcCmdMgr.addCommand(new CmdPartDesignPolarPattern()); - //rcCmdMgr.addCommand(new CmdPartDesignScaled()); - rcCmdMgr.addCommand(new CmdPartDesignMultiTransform()); - - rcCmdMgr.addCommand(new CmdPartDesignBoolean()); -} diff --git a/src/Mod/PartDesign/Gui/FeaturePickDialog.cpp.orig b/src/Mod/PartDesign/Gui/FeaturePickDialog.cpp.orig deleted file mode 100644 index 598d7bb96..000000000 --- a/src/Mod/PartDesign/Gui/FeaturePickDialog.cpp.orig +++ /dev/null @@ -1,166 +0,0 @@ -/****************************************************************************** - * Copyright (c)2012 Jan Rheinlaender * - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file COPYING.LIB. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * - ******************************************************************************/ - -#include "PreCompiled.h" - -#ifndef _PreComp_ -# include -# include -# include -#endif - -#include -#include -#include -#include -#include - -#include "ui_FeaturePickDialog.h" -#include "FeaturePickDialog.h" - -using namespace PartDesignGui; - -const QString FeaturePickDialog::getFeatureStatusString(const featureStatus st) -{ - switch (st) { - case validFeature: return tr("Valid"); - case invalidShape: return tr("Invalid shape"); - case noWire: return tr("No wire in sketch"); - case isUsed: return tr("Sketch already used by other feature"); - case otherBody: return tr("Sketch belongs to another Body feature"); - } - - return tr(""); -} - -FeaturePickDialog::FeaturePickDialog(std::vector& objects, - const std::vector& status) - : QDialog(Gui::getMainWindow()), ui(new Ui_FeaturePickDialog) -{ - ui->setupUi(this); -<<<<<<< 90079612b9f3db27654ac1d04ee2262d99842e1b - for (std::vector::const_iterator o = objects.begin(); o != objects.end(); ++o) - ui->listWidget->addItem(QString::fromLatin1((*o)->getNameInDocument())); -======= - - connect(ui->checkOtherBody, SIGNAL(toggled(bool)), this, SLOT(onCheckOtherBody(bool))); - connect(ui->checkOtherFeature, SIGNAL(toggled(bool)), this, SLOT(onCheckOtherFeature(bool))); - connect(ui->radioIndependent, SIGNAL(toggled(bool)), this, SLOT(onUpdate(bool))); - connect(ui->radioDependent, SIGNAL(toggled(bool)), this, SLOT(onUpdate(bool))); - connect(ui->radioXRef, SIGNAL(toggled(bool)), this, SLOT(onUpdate(bool))); - - ui->checkOtherBody->setChecked(false); - ui->checkOtherBody->setEnabled(false); // TODO: implement - ui->checkOtherFeature->setChecked(false); - ui->checkOtherFeature->setEnabled(false); // TODO: implement - ui->radioIndependent->setChecked(true); - ui->radioIndependent->setEnabled(false); - // These are not implemented yet - ui->radioDependent->setEnabled(false); - ui->radioXRef->setEnabled(false); - - std::vector::const_iterator st = status.begin(); - for (std::vector::const_iterator o = objects.begin(); o != objects.end(); ++o) { - QListWidgetItem* item = new QListWidgetItem(QString::fromAscii((*o)->getNameInDocument()) + - QString::fromAscii(" (") + getFeatureStatusString(*st) + QString::fromAscii(")")); - ui->listWidget->addItem(item); - st++; - } - - statuses = status; - updateList(); ->>>>>>> Enhanced Pick dialog for PartDesign feature's sketches -} - -FeaturePickDialog::~FeaturePickDialog() -{ - -} - -void FeaturePickDialog::updateList() -{ - int index = 0; - - for (std::vector::const_iterator st = statuses.begin(); st != statuses.end(); st++) { - QListWidgetItem* item = ui->listWidget->item(index); - - switch (*st) { - case validFeature: item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); break; - case invalidShape: item->setFlags(Qt::NoItemFlags); break; - case noWire: item->setFlags(Qt::NoItemFlags); break; - case isUsed: item->setFlags(ui->checkOtherFeature->isChecked() ? Qt::ItemIsSelectable | Qt::ItemIsEnabled : Qt::NoItemFlags); break; - case otherBody: item->setFlags(ui->checkOtherBody->isChecked() ? Qt::ItemIsSelectable | Qt::ItemIsEnabled : Qt::NoItemFlags); break; - } - - index++; - } -} - -void FeaturePickDialog::onCheckOtherFeature(bool checked) -{ - ui->radioIndependent->setEnabled(checked); - // TODO: Not implemented yet - //ui->radioDependent->setEnabled(checked); - //ui->radioXRef->setEnabled(checked); - - updateList(); -} - -void FeaturePickDialog::onCheckOtherBody(bool checked) -{ - ui->radioIndependent->setEnabled(checked); - // TODO: Not implemented yet - //ui->radioDependent->setEnabled(checked); - //ui->radioXRef->setEnabled(checked); - - updateList(); -} - -void FeaturePickDialog::onUpdate(bool) -{ - updateList(); -} - -std::vector FeaturePickDialog::getFeatures() { - std::vector result; - - for (std::vector::const_iterator s = features.begin(); s != features.end(); ++s) - result.push_back(App::GetApplication().getActiveDocument()->getObject(s->toLatin1().data())); - - return result; -} - - - -void FeaturePickDialog::accept() -{ - features.clear(); - QListIterator i(ui->listWidget->selectedItems()); - while (i.hasNext()) { - QString t = i.next()->text(); - t = t.left(t.indexOf(QString::fromAscii("(")) - 1); - features.push_back(t); - } - - QDialog::accept(); -} -#include "moc_FeaturePickDialog.cpp" diff --git a/src/Mod/PartDesign/Gui/Resources/PartDesign.qrc.orig b/src/Mod/PartDesign/Gui/Resources/PartDesign.qrc.orig deleted file mode 100644 index 24fa4ae18..000000000 --- a/src/Mod/PartDesign/Gui/Resources/PartDesign.qrc.orig +++ /dev/null @@ -1,79 +0,0 @@ - - - icons/PartDesign_Chamfer.svg - icons/PartDesign_Fillet.svg - icons/PartDesign_Draft.svg - icons/PartDesign_Thickness.svg - icons/PartDesign_Groove.svg - icons/PartDesign_Pad.svg - icons/PartDesign_Pocket.svg - icons/PartDesign_Revolution.svg - icons/PartDesign_Mirrored.svg - icons/PartDesign_LinearPattern.svg - icons/PartDesign_PolarPattern.svg - icons/PartDesign_Scaled.svg - icons/PartDesign_MultiTransform.svg - icons/PartDesign_Hole.svg - icons/PartDesign_Body.svg - icons/PartDesign_Boolean.svg - icons/PartDesign_Plane.svg - icons/PartDesign_Line.svg - icons/PartDesign_Point.svg - icons/PartDesign_CoordinateSystem.svg - icons/PartDesign_MoveTip.svg - icons/Tree_PartDesign_Pad.svg - icons/Tree_PartDesign_Revolution.svg - icons/PartDesign_InternalExternalGear.svg - icons/PartDesign_InvoluteGear.svg -<<<<<<< a6cae97ea944460d610fe5b54eee2890a927dc00 - icons/PartDesignWorkbench.svg - icons/PartDesign_Body_Create_New.svg -======= - icons/PartDesign_Body_Create_New.svg ->>>>>>> add basic part design pipe infrastructure - icons/PartDesign_Body_Tree.svg - icons/PartDesign_Additive_Pipe.svg - icons/PartDesign_Additive_Box.svg - icons/PartDesign_Additive_Cylinder.svg - icons/PartDesign_Additive_Sphere.svg - icons/PartDesign_Additive_Cone.svg - icons/PartDesign_Additive_Torus.svg - icons/PartDesign_Additive_Ellipsoid.svg - icons/PartDesign_Additive_Prism.svg - icons/PartDesign_Additive_Wedge.svg - icons/PartDesign_Subtractive_Box.svg - icons/PartDesign_Subtractive_Cylinder.svg - icons/PartDesign_Subtractive_Sphere.svg - icons/PartDesign_Subtractive_Cone.svg - icons/PartDesign_Subtractive_Torus.svg - icons/PartDesign_Subtractive_Ellipsoid.svg - icons/PartDesign_Subtractive_Prism.svg - icons/PartDesign_Subtractive_Wedge.svg - translations/PartDesign_af.qm - translations/PartDesign_de.qm - translations/PartDesign_fi.qm - translations/PartDesign_fr.qm - translations/PartDesign_hr.qm - translations/PartDesign_it.qm - translations/PartDesign_nl.qm - translations/PartDesign_no.qm - translations/PartDesign_pl.qm - translations/PartDesign_ru.qm - translations/PartDesign_uk.qm - translations/PartDesign_tr.qm - translations/PartDesign_sv-SE.qm - translations/PartDesign_zh-TW.qm - translations/PartDesign_pt-BR.qm - translations/PartDesign_cs.qm - translations/PartDesign_sk.qm - translations/PartDesign_es-ES.qm - translations/PartDesign_zh-CN.qm - translations/PartDesign_ja.qm - translations/PartDesign_ro.qm - translations/PartDesign_hu.qm - translations/PartDesign_pt-PT.qm - translations/PartDesign_sr.qm - translations/PartDesign_el.qm - translations/PartDesign_sl.qm - - diff --git a/src/Mod/PartDesign/Gui/TaskChamferParameters.h.orig b/src/Mod/PartDesign/Gui/TaskChamferParameters.h.orig deleted file mode 100644 index 517790999..000000000 --- a/src/Mod/PartDesign/Gui/TaskChamferParameters.h.orig +++ /dev/null @@ -1,90 +0,0 @@ -/*************************************************************************** - * Copyright (c) 2011 Juergen Riegel * - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file COPYING.LIB. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * - ***************************************************************************/ - - -#ifndef GUI_TASKVIEW_TaskChamferParameters_H -#define GUI_TASKVIEW_TaskChamferParameters_H - -#include "TaskDressUpParameters.h" -#include "ViewProviderChamfer.h" - -class Ui_TaskChamferParameters; - -namespace PartDesignGui { - -class TaskChamferParameters : public TaskDressUpParameters -{ - Q_OBJECT - -public: - TaskChamferParameters(ViewProviderDressUp *DressUpView, QWidget *parent=0); - ~TaskChamferParameters(); - - virtual void apply(); - -private Q_SLOTS: - void onLengthChanged(double); - void onRefDeleted(void); - -protected: - virtual void clearButtons(const selectionModes notThis); - void changeEvent(QEvent *e); - virtual void onSelectionChanged(const Gui::SelectionChanges& msg); - double getLength(void) const; - -private: - Ui_TaskChamferParameters* ui; -}; - -/// simulation dialog for the TaskView -class TaskDlgChamferParameters : public TaskDlgDressUpParameters -{ - Q_OBJECT - -public: - TaskDlgChamferParameters(ViewProviderChamfer *DressUpView); - ~TaskDlgChamferParameters(); - -public: - /// is called by the framework if the dialog is accepted (Ok) - virtual bool accept(); -<<<<<<< 61d7568d0ff2d3e87f1abb738517f4294c5a6d2e - /// is called by the framework if the dialog is rejected (Cancel) - virtual bool reject(); - virtual bool isAllowedAlterDocument(void) const - { return false; } - - /// returns for Close and Help button - virtual QDialogButtonBox::StandardButtons getStandardButtons(void) const - { return QDialogButtonBox::Ok|QDialogButtonBox::Cancel; } - -protected: - ViewProviderChamfer *ChamferView; - - TaskChamferParameters *parameter; -======= ->>>>>>> Allow selecting and removing fillet and chamfer references in the dialog -}; - -} //namespace PartDesignGui - -#endif // GUI_TASKVIEW_TaskChamferParameters_H diff --git a/src/Mod/PartDesign/Gui/TaskDraftParameters.cpp.orig b/src/Mod/PartDesign/Gui/TaskDraftParameters.cpp.orig deleted file mode 100644 index 37cd97bfd..000000000 --- a/src/Mod/PartDesign/Gui/TaskDraftParameters.cpp.orig +++ /dev/null @@ -1,332 +0,0 @@ -/*************************************************************************** - * Copyright (c) 2012 Jan Rheinländer * - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file COPYING.LIB. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * - ***************************************************************************/ - - -#include "PreCompiled.h" - -#ifndef _PreComp_ -# include -#endif - -#include "ui_TaskDraftParameters.h" -#include "TaskDraftParameters.h" -#include "Workbench.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace PartDesignGui; -using namespace Gui; - -/* TRANSLATOR PartDesignGui::TaskDraftParameters */ - -TaskDraftParameters::TaskDraftParameters(ViewProviderDressUp *DressUpView,QWidget *parent) - : TaskDressUpParameters(DressUpView, parent) -{ - // we need a separate container widget to add all controls to - proxy = new QWidget(this); - ui = new Ui_TaskDraftParameters(); - ui->setupUi(proxy); - QMetaObject::connectSlotsByName(this); - - connect(ui->draftAngle, SIGNAL(valueChanged(double)), - this, SLOT(onAngleChanged(double))); - connect(ui->checkReverse, SIGNAL(toggled(bool)), - this, SLOT(onReversedChanged(bool))); - connect(ui->buttonRefAdd, SIGNAL(toggled(bool)), - this, SLOT(onButtonRefAdd(bool))); - connect(ui->buttonRefRemove, SIGNAL(toggled(bool)), - this, SLOT(onButtonRefRemove(bool))); - connect(ui->buttonPlane, SIGNAL(toggled(bool)), - this, SLOT(onButtonPlane(bool))); - connect(ui->buttonLine, SIGNAL(toggled(bool)), - this, SLOT(onButtonLine(bool))); - - this->groupLayout()->addWidget(proxy); - - PartDesign::Draft* pcDraft = static_cast(DressUpView->getObject()); - double a = pcDraft->Angle.getValue(); - - ui->draftAngle->setMinimum(0.0); - ui->draftAngle->setMaximum(89.99); - ui->draftAngle->setValue(a); - ui->draftAngle->selectAll(); - QMetaObject::invokeMethod(ui->draftAngle, "setFocus", Qt::QueuedConnection); - - bool r = pcDraft->Reversed.getValue(); - ui->checkReverse->setChecked(r); - - std::vector strings = pcDraft->Base.getSubValues(); - for (std::vector::const_iterator i = strings.begin(); i != strings.end(); ++i) - { - ui->listWidgetReferences->insertItem(0, QString::fromStdString(*i)); - } - // Create context menu - QAction* action = new QAction(tr("Remove"), this); - ui->listWidgetReferences->addAction(action); - connect(action, SIGNAL(triggered()), this, SLOT(onRefDeleted())); - ui->listWidgetReferences->setContextMenuPolicy(Qt::ActionsContextMenu); - - App::DocumentObject* ref = pcDraft->NeutralPlane.getValue(); - strings = pcDraft->NeutralPlane.getSubValues(); - ui->linePlane->setText(getRefStr(ref, strings)); - - ref = pcDraft->PullDirection.getValue(); - strings = pcDraft->PullDirection.getSubValues(); - ui->lineLine->setText(getRefStr(ref, strings)); -} - -void TaskDraftParameters::onSelectionChanged(const Gui::SelectionChanges& msg) -{ - if (selectionMode == none) - return; - - if (msg.Type == Gui::SelectionChanges::AddSelection) { - if (referenceSelected(msg)) { - if (selectionMode == refAdd) - ui->listWidgetReferences->insertItem(0, QString::fromStdString(msg.pSubName)); - else - removeItemFromListWidget(ui->listWidgetReferences, msg.pSubName); - clearButtons(none); - exitSelectionMode(); - } else if (selectionMode == plane) { - PartDesign::Draft* pcDraft = static_cast(DressUpView->getObject()); - std::vector planes; - App::DocumentObject* selObj; - getReferencedSelection(pcDraft, msg, selObj, planes); - pcDraft->NeutralPlane.setValue(selObj, planes); - ui->linePlane->setText(getRefStr(selObj, planes)); - - pcDraft->getDocument()->recomputeFeature(pcDraft); - clearButtons(none); - exitSelectionMode(); - } else if (selectionMode == line) { - PartDesign::Draft* pcDraft = static_cast(DressUpView->getObject()); - std::vector edges; - App::DocumentObject* selObj; - getReferencedSelection(pcDraft, msg, selObj, edges); - pcDraft->PullDirection.setValue(selObj, edges); - ui->lineLine->setText(getRefStr(selObj, edges)); - - pcDraft->getDocument()->recomputeFeature(pcDraft); - clearButtons(none); - exitSelectionMode(); - } - } -} - -void TaskDraftParameters::clearButtons(const selectionModes notThis) -{ - if (notThis != refAdd) ui->buttonRefAdd->setChecked(false); - if (notThis != refRemove) ui->buttonRefRemove->setChecked(false); - if (notThis != line) ui->buttonLine->setChecked(false); - if (notThis != plane) ui->buttonPlane->setChecked(false); -} - -void TaskDraftParameters::onButtonPlane(bool checked) -{ - if (checked) { - clearButtons(plane); - hideObject(); - selectionMode = plane; - Gui::Selection().clearSelection(); - Gui::Selection().addSelectionGate(new ReferenceSelection(this->getBase(), true, true, true)); - } -} - -void TaskDraftParameters::onButtonLine(bool checked) -{ - if (checked) { - clearButtons(line); - hideObject(); - selectionMode = line; - Gui::Selection().clearSelection(); - Gui::Selection().addSelectionGate(new ReferenceSelection(this->getBase(), true, false, true)); - } -} - -void TaskDraftParameters::onRefDeleted(void) -{ - PartDesign::Draft* pcDraft = static_cast(DressUpView->getObject()); - App::DocumentObject* base = pcDraft->Base.getValue(); - std::vector faces = pcDraft->Base.getSubValues(); - faces.erase(faces.begin() + ui->listWidgetReferences->currentRow()); - pcDraft->Base.setValue(base, faces); - ui->listWidgetReferences->model()->removeRow(ui->listWidgetReferences->currentRow()); - pcDraft->getDocument()->recomputeFeature(pcDraft); -} - -void TaskDraftParameters::getPlane(App::DocumentObject*& obj, std::vector& sub) const -{ - sub = std::vector(1,""); - QStringList parts = ui->linePlane->text().split(QChar::fromAscii(':')); - obj = DressUpView->getObject()->getDocument()->getObject(parts[0].toStdString().c_str()); - if (parts.size() > 1) - sub[0] = parts[1].toStdString(); -} - -void TaskDraftParameters::getLine(App::DocumentObject*& obj, std::vector& sub) const -{ - sub = std::vector(1,""); - QStringList parts = ui->lineLine->text().split(QChar::fromAscii(':')); - obj = DressUpView->getObject()->getDocument()->getObject(parts[0].toStdString().c_str()); - if (parts.size() > 1) - sub[0] = parts[1].toStdString(); -} - -void TaskDraftParameters::onAngleChanged(double angle) -{ - clearButtons(none); - PartDesign::Draft* pcDraft = static_cast(DressUpView->getObject()); - pcDraft->Angle.setValue(angle); - pcDraft->getDocument()->recomputeFeature(pcDraft); -} - -const double TaskDraftParameters::getAngle(void) const -{ - return ui->draftAngle->value().getValue(); -} - -void TaskDraftParameters::onReversedChanged(const bool on) { - clearButtons(none); - PartDesign::Draft* pcDraft = static_cast(DressUpView->getObject()); - pcDraft->Reversed.setValue(on); - pcDraft->getDocument()->recomputeFeature(pcDraft); -} - -const bool TaskDraftParameters::getReversed(void) const -{ - return ui->checkReverse->isChecked(); -} - -TaskDraftParameters::~TaskDraftParameters() -{ - Gui::Selection().rmvSelectionGate(); - delete ui; -} - -void TaskDraftParameters::changeEvent(QEvent *e) -{ - TaskBox::changeEvent(e); - if (e->type() == QEvent::LanguageChange) { - ui->retranslateUi(proxy); - } -} - - -//************************************************************************** -//************************************************************************** -// TaskDialog -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -TaskDlgDraftParameters::TaskDlgDraftParameters(ViewProviderDraft *DressUpView) - : TaskDlgDressUpParameters(DressUpView) -{ - parameter = new TaskDraftParameters(DressUpView); - - Content.push_back(parameter); -} - -TaskDlgDraftParameters::~TaskDlgDraftParameters() -{ - -} - -//==== calls from the TaskView =============================================================== - - -//void TaskDlgDraftParameters::open() -//{ -// // a transaction is already open at creation time of the draft -// if (!Gui::Command::hasPendingCommand()) { -// QString msg = QObject::tr("Edit draft"); -// Gui::Command::openCommand((const char*)msg.toUtf8()); -// } -//} - -bool TaskDlgDraftParameters::accept() -{ - parameter->showObject(); - - // Force the user to select a neutral plane - std::vector strings; - App::DocumentObject* obj; - TaskDraftParameters* draftparameter = static_cast(parameter); - draftparameter->getPlane(obj, strings); - std::string neutralPlane = getPythonStr(obj, strings); - if (neutralPlane.empty()) { - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Missing neutral plane"), - QObject::tr("Please select a plane or an edge plus a pull direction")); - return false; - } - -<<<<<<< 7e34fb3b6f610a533bbd50991d4b09cf063cda7b - std::string name = DraftView->getObject()->getNameInDocument(); - - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Angle = %f",name.c_str(),parameter->getAngle()); - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Reversed = %u",name.c_str(),parameter->getReversed()); - try { - std::vector faces = parameter->getFaces(); - std::stringstream str; - str << "App.ActiveDocument." << name.c_str() << ".Base = (App.ActiveDocument." - << parameter->getBase()->getNameInDocument() << ",["; - for (std::vector::const_iterator it = faces.begin(); it != faces.end(); ++it) - str << "\"" << *it << "\","; - str << "])"; - Gui::Command::doCommand(Gui::Command::Doc,str.str().c_str()); - } - catch (const Base::Exception& e) { - QMessageBox::warning(parameter, tr("Input error"), QString::fromLatin1(e.what())); - return false; - } -======= - std::string name = DressUpView->getObject()->getNameInDocument(); - - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Angle = %f",name.c_str(),draftparameter->getAngle()); - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Reversed = %u",name.c_str(),draftparameter->getReversed()); ->>>>>>> Unify code of Dressup features (part 1: Draft) - if (!neutralPlane.empty()) { - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.NeutralPlane = %s", name.c_str(), neutralPlane.c_str()); - } else - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.NeutralPlane = None", name.c_str()); - draftparameter->getLine(obj, strings); - std::string pullDirection = getPythonStr(obj, strings); - if (!pullDirection.empty()) { - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.PullDirection = %s", name.c_str(), pullDirection.c_str()); - } else - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.PullDirection = None", name.c_str()); - - return TaskDlgDressUpParameters::accept(); -} - -#include "moc_TaskDraftParameters.cpp" diff --git a/src/Mod/PartDesign/Gui/TaskDraftParameters.h.orig b/src/Mod/PartDesign/Gui/TaskDraftParameters.h.orig deleted file mode 100644 index 87b605263..000000000 --- a/src/Mod/PartDesign/Gui/TaskDraftParameters.h.orig +++ /dev/null @@ -1,96 +0,0 @@ -/*************************************************************************** - * Copyright (c) 2012 Jan Rheinländer * - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file COPYING.LIB. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * - ***************************************************************************/ - - -#ifndef GUI_TASKVIEW_TaskDraftParameters_H -#define GUI_TASKVIEW_TaskDraftParameters_H - -#include "TaskDressUpParameters.h" -#include "ViewProviderDraft.h" - -class Ui_TaskDraftParameters; - -namespace PartDesignGui { - -class TaskDraftParameters : public TaskDressUpParameters -{ - Q_OBJECT - -public: - TaskDraftParameters(ViewProviderDressUp *DressUpView, QWidget *parent=0); - ~TaskDraftParameters(); - - const double getAngle(void) const; - const bool getReversed(void) const; - const std::vector getFaces(void) const; - void getPlane(App::DocumentObject*& obj, std::vector& sub) const; - void getLine(App::DocumentObject*& obj, std::vector& sub) const; - -private Q_SLOTS: - void onAngleChanged(double angle); - void onReversedChanged(bool reversed); - void onButtonPlane(const bool checked); - void onButtonLine(const bool checked); - void onRefDeleted(void); - -protected: - virtual void clearButtons(const selectionModes notThis); - void changeEvent(QEvent *e); - virtual void onSelectionChanged(const Gui::SelectionChanges& msg); - -private: - Ui_TaskDraftParameters* ui; -}; - -/// simulation dialog for the TaskView -class TaskDlgDraftParameters : public TaskDlgDressUpParameters -{ - Q_OBJECT - -public: - TaskDlgDraftParameters(ViewProviderDraft *DraftView); - ~TaskDlgDraftParameters(); - -public: - /// is called by the framework if the dialog is accepted (Ok) - virtual bool accept(); -<<<<<<< 7e34fb3b6f610a533bbd50991d4b09cf063cda7b - /// is called by the framework if the dialog is rejected (Cancel) - virtual bool reject(); - virtual bool isAllowedAlterDocument(void) const - { return false; } - - /// returns for Close and Help button - virtual QDialogButtonBox::StandardButtons getStandardButtons(void) const - { return QDialogButtonBox::Ok|QDialogButtonBox::Cancel; } - -protected: - ViewProviderDraft *DraftView; - - TaskDraftParameters *parameter; -======= ->>>>>>> Unify code of Dressup features (part 1: Draft) -}; - -} //namespace PartDesignGui - -#endif // GUI_TASKVIEW_TASKAPPERANCE_H diff --git a/src/Mod/PartDesign/Gui/TaskFilletParameters.h.orig b/src/Mod/PartDesign/Gui/TaskFilletParameters.h.orig deleted file mode 100644 index 17f2a4e7c..000000000 --- a/src/Mod/PartDesign/Gui/TaskFilletParameters.h.orig +++ /dev/null @@ -1,90 +0,0 @@ -/*************************************************************************** - * Copyright (c) 2011 Juergen Riegel * - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file COPYING.LIB. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * - ***************************************************************************/ - - -#ifndef GUI_TASKVIEW_TaskFilletParameters_H -#define GUI_TASKVIEW_TaskFilletParameters_H - -#include "TaskDressUpParameters.h" -#include "ViewProviderFillet.h" - -class Ui_TaskFilletParameters; - -namespace PartDesignGui { - -class TaskFilletParameters : public TaskDressUpParameters -{ - Q_OBJECT - -public: - TaskFilletParameters(ViewProviderDressUp *DressUpView, QWidget *parent=0); - ~TaskFilletParameters(); - - virtual void apply(); - -private Q_SLOTS: - void onLengthChanged(double); - void onRefDeleted(void); - -protected: - double getLength(void) const; - virtual void clearButtons(const selectionModes notThis); - void changeEvent(QEvent *e); - virtual void onSelectionChanged(const Gui::SelectionChanges& msg); - -private: - Ui_TaskFilletParameters* ui; -}; - -/// simulation dialog for the TaskView -class TaskDlgFilletParameters : public TaskDlgDressUpParameters -{ - Q_OBJECT - -public: - TaskDlgFilletParameters(ViewProviderFillet *DressUpView); - ~TaskDlgFilletParameters(); - -public: - /// is called by the framework if the dialog is accepted (Ok) - virtual bool accept(); -<<<<<<< 61d7568d0ff2d3e87f1abb738517f4294c5a6d2e - /// is called by the framework if the dialog is rejected (Cancel) - virtual bool reject(); - virtual bool isAllowedAlterDocument(void) const - { return false; } - - /// returns for Close and Help button - virtual QDialogButtonBox::StandardButtons getStandardButtons(void) const - { return QDialogButtonBox::Ok|QDialogButtonBox::Cancel; } - -protected: - ViewProviderFillet *FilletView; - - TaskFilletParameters *parameter; -======= ->>>>>>> Allow selecting and removing fillet and chamfer references in the dialog -}; - -} //namespace PartDesignGui - -#endif // GUI_TASKVIEW_TaskFilletParameters_H diff --git a/src/Mod/PartDesign/Gui/TaskGrooveParameters.cpp.orig b/src/Mod/PartDesign/Gui/TaskGrooveParameters.cpp.orig deleted file mode 100644 index e365cc7b2..000000000 --- a/src/Mod/PartDesign/Gui/TaskGrooveParameters.cpp.orig +++ /dev/null @@ -1,458 +0,0 @@ -/****************************************************************************** - * Copyright (c)2012 Jan Rheinlaender * - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file COPYING.LIB. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * - ******************************************************************************/ - - -#include "PreCompiled.h" - -#ifndef _PreComp_ -#endif - -#include "ui_TaskGrooveParameters.h" -#include "TaskGrooveParameters.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "Workbench.h" -#include "ReferenceSelection.h" -#include "TaskSketchBasedParameters.h" - -using namespace PartDesignGui; -using namespace Gui; - -/* TRANSLATOR PartDesignGui::TaskGrooveParameters */ - -TaskGrooveParameters::TaskGrooveParameters(ViewProviderGroove *GrooveView,QWidget *parent) - : TaskSketchBasedParameters(GrooveView, parent, "PartDesign_Groove",tr("Groove parameters")) -{ - // we need a separate container widget to add all controls to - proxy = new QWidget(this); - ui = new Ui_TaskGrooveParameters(); - ui->setupUi(proxy); - QMetaObject::connectSlotsByName(this); - - connect(ui->grooveAngle, SIGNAL(valueChanged(double)), - this, SLOT(onAngleChanged(double))); - connect(ui->axis, SIGNAL(activated(int)), - this, SLOT(onAxisChanged(int))); - connect(ui->checkBoxMidplane, SIGNAL(toggled(bool)), - this, SLOT(onMidplane(bool))); - connect(ui->checkBoxReversed, SIGNAL(toggled(bool)), - this, SLOT(onReversed(bool))); - connect(ui->checkBoxUpdateView, SIGNAL(toggled(bool)), - this, SLOT(onUpdateView(bool))); - - this->groupLayout()->addWidget(proxy); - - // Temporarily prevent unnecessary feature updates - ui->grooveAngle->blockSignals(true); - ui->axis->blockSignals(true); - ui->checkBoxMidplane->blockSignals(true); - ui->checkBoxReversed->blockSignals(true); - - PartDesign::Groove* pcGroove = static_cast(vp->getObject()); - double l = pcGroove->Angle.getValue(); - bool mirrored = pcGroove->Midplane.getValue(); - bool reversed = pcGroove->Reversed.getValue(); - - ui->grooveAngle->setValue(l); - ui->grooveAngle->bind(pcGroove->Angle); - -<<<<<<< f0798a82fe8f03db57aca4f634d2123486daaea0 - int count=pcGroove->getSketchAxisCount(); - - for (int i=ui->axis->count()-1; i >= count+2; i--) - ui->axis->removeItem(i); - for (int i=ui->axis->count(); i < count+2; i++) - ui->axis->addItem(QString::fromLatin1("Sketch axis %1").arg(i-2)); - - int pos=-1; - - App::DocumentObject *pcReferenceAxis = pcGroove->ReferenceAxis.getValue(); - const std::vector &subReferenceAxis = pcGroove->ReferenceAxis.getSubValues(); - if (pcReferenceAxis && pcReferenceAxis == pcGroove->Sketch.getValue()) { - assert(subReferenceAxis.size()==1); - if (subReferenceAxis[0] == "V_Axis") - pos = 0; - else if (subReferenceAxis[0] == "H_Axis") - pos = 1; - else if (subReferenceAxis[0].size() > 4 && subReferenceAxis[0].substr(0,4) == "Axis") - pos = 2 + std::atoi(subReferenceAxis[0].substr(4,4000).c_str()); - } - - if (pos < 0 || pos >= ui->axis->count()) { - ui->axis->addItem(QString::fromLatin1("Undefined")); - pos = ui->axis->count()-1; - } - - ui->axis->setCurrentIndex(pos); -======= - blockUpdate = false; - updateUI(); ->>>>>>> Enable edges and datum lines as rotation axis for Groove and Revolution features - - ui->checkBoxMidplane->setChecked(mirrored); - ui->checkBoxReversed->setChecked(reversed); - - ui->grooveAngle->blockSignals(false); - ui->axis->blockSignals(false); - ui->checkBoxMidplane->blockSignals(false); - ui->checkBoxReversed->blockSignals(false); - - setFocus (); -} - -void TaskGrooveParameters::updateUI() -{ - if (blockUpdate) - return; - blockUpdate = true; - - PartDesign::Groove* pcGroove = static_cast(vp->getObject()); - - App::DocumentObject* pcReferenceAxis = pcGroove->ReferenceAxis.getValue(); - std::vector sub = pcGroove->ReferenceAxis.getSubValues(); - - // Add user-defined sketch axes to the reference selection combo box - Sketcher::SketchObject *pcSketch = static_cast(pcGroove->Sketch.getValue()); - int maxcount=2; - if (pcSketch) - maxcount += pcSketch->getAxisCount(); - - for (int i=ui->axis->count()-1; i >= 2; i--) - ui->axis->removeItem(i); - for (int i=ui->axis->count(); i < maxcount; i++) - ui->axis->addItem(QString::fromAscii("Sketch axis %1").arg(i-5)); - - bool undefined = false; - if (pcReferenceAxis != NULL && !sub.empty()) { - if (sub.front() == "H_Axis") - ui->axis->setCurrentIndex(0); - else if (sub.front() == "V_Axis") - ui->axis->setCurrentIndex(1); - else if (sub.front().size() > 4 && sub.front().substr(0,4) == "Axis") { - int pos = 2 + std::atoi(sub.front().substr(4,4000).c_str()); - if (pos <= maxcount) - ui->axis->setCurrentIndex(pos); - else - undefined = true; - } else { - ui->axis->addItem(getRefStr(pcReferenceAxis, sub)); - ui->axis->setCurrentIndex(maxcount); - } - } else { - undefined = true; - } - - ui->axis->addItem(tr("Select reference...")); - - blockUpdate = false; -} - -void TaskGrooveParameters::onSelectionChanged(const Gui::SelectionChanges& msg) -{ - if (msg.Type == Gui::SelectionChanges::AddSelection) { - PartDesign::Groove* pcGroove = static_cast(vp->getObject()); - - exitSelectionMode(); - if (!blockUpdate) { - std::vector axis; - App::DocumentObject* selObj; - getReferencedSelection(pcGroove, msg, selObj, axis); - pcGroove->ReferenceAxis.setValue(selObj, axis); - - - recomputeFeature(); - updateUI(); - } - else { - Sketcher::SketchObject *pcSketch = static_cast(pcGroove->Sketch.getValue()); - int maxcount=2; - if (pcSketch) - maxcount += pcSketch->getAxisCount(); - for (int i=ui->axis->count()-1; i >= maxcount; i--) - ui->axis->removeItem(i); - - std::vector sub; - App::DocumentObject* selObj; - getReferencedSelection(pcGroove, msg, selObj, sub); - ui->axis->addItem(getRefStr(selObj, sub)); - ui->axis->setCurrentIndex(maxcount); - ui->axis->addItem(tr("Select reference...")); - } - } -} - -void TaskGrooveParameters::onAngleChanged(double len) -{ - PartDesign::Groove* pcGroove = static_cast(vp->getObject()); - pcGroove->Angle.setValue(len); - exitSelectionMode(); - recomputeFeature(); -} - -void TaskGrooveParameters::onAxisChanged(int num) -{ - if (blockUpdate) - return; - PartDesign::Groove* pcGroove = static_cast(vp->getObject()); - Sketcher::SketchObject *pcSketch = static_cast(pcGroove->Sketch.getValue()); - if (pcSketch) { - App::DocumentObject *oldRefAxis = pcGroove->ReferenceAxis.getValue(); - std::vector oldSubRefAxis = pcGroove->ReferenceAxis.getSubValues(); - - int maxcount = pcSketch->getAxisCount()+2; - if (num == 0) { - pcGroove->ReferenceAxis.setValue(pcSketch, std::vector(1,"H_Axis")); - exitSelectionMode(); - } else if (num == 1) { - pcGroove->ReferenceAxis.setValue(pcSketch, std::vector(1,"V_Axis")); - exitSelectionMode(); - } else if (num >= 2 && num < maxcount) { - QString buf = QString::fromUtf8("Axis%1").arg(num-2); - std::string str = buf.toStdString(); - pcGroove->ReferenceAxis.setValue(pcSketch, std::vector(1,str)); - exitSelectionMode(); - } else if (num == ui->axis->count() - 1) { - // enter reference selection mode - TaskSketchBasedParameters::onSelectReference(true, true, false, true); - } else if (num == maxcount) - exitSelectionMode(); - - App::DocumentObject *newRefAxis = pcGroove->ReferenceAxis.getValue(); - const std::vector &newSubRefAxis = pcGroove->ReferenceAxis.getSubValues(); - if (oldRefAxis != newRefAxis || - oldSubRefAxis.size() != newSubRefAxis.size() || - oldSubRefAxis[0] != newSubRefAxis[0]) { - bool reversed = pcGroove->suggestReversed(); - if (reversed != pcGroove->Reversed.getValue()) { - pcGroove->Reversed.setValue(reversed); - ui->checkBoxReversed->blockSignals(true); - ui->checkBoxReversed->setChecked(reversed); - ui->checkBoxReversed->blockSignals(false); - } - } - } - - updateUI(); - recomputeFeature(); -} - -void TaskGrooveParameters::onMidplane(bool on) -{ - PartDesign::Groove* pcGroove = static_cast(vp->getObject()); - pcGroove->Midplane.setValue(on); - recomputeFeature(); -} - -void TaskGrooveParameters::onReversed(bool on) -{ - PartDesign::Groove* pcGroove = static_cast(vp->getObject()); - pcGroove->Reversed.setValue(on); - recomputeFeature(); -} - -double TaskGrooveParameters::getAngle(void) const -{ - return ui->grooveAngle->value().getValue(); -} - -void TaskGrooveParameters::getReferenceAxis(App::DocumentObject*& obj, std::vector& sub) const -{ - // get the support and Sketch - PartDesign::Groove* pcGroove = static_cast(vp->getObject()); - obj = static_cast(pcGroove->Sketch.getValue()); - sub = std::vector(1,""); - int maxcount=2; - if (obj) - maxcount += static_cast(obj)->getAxisCount(); - - if (obj) { - int num = ui->axis->currentIndex(); - if (num == 0) - sub[0] = "H_Axis"; - else if (num == 1) - sub[0] = "V_Axis"; - else if (num >= 2 && num < maxcount) { - QString buf = QString::fromUtf8("Axis%1").arg(num-2); - sub[0] = buf.toStdString(); - } else if (num == maxcount && ui->axis->count() == maxcount + 2) { - QStringList parts = ui->axis->currentText().split(QChar::fromAscii(':')); - obj = vp->getObject()->getDocument()->getObject(parts[0].toStdString().c_str()); - if (parts.size() > 1) - sub[0] = parts[1].toStdString(); - } else { - obj = NULL; - } - } - else - obj = NULL; -} - -bool TaskGrooveParameters::getMidplane(void) const -{ - return ui->checkBoxMidplane->isChecked(); -} - -bool TaskGrooveParameters::getReversed(void) const -{ - return ui->checkBoxReversed->isChecked(); -} - -TaskGrooveParameters::~TaskGrooveParameters() -{ - delete ui; -} - -void TaskGrooveParameters::changeEvent(QEvent *e) -{ - TaskBox::changeEvent(e); - if (e->type() == QEvent::LanguageChange) { - ui->retranslateUi(proxy); - } -} - -void TaskGrooveParameters::apply() -{ - App::DocumentObject* groove = vp->getObject(); - std::string name = groove->getNameInDocument(); - - // retrieve sketch and its support object - App::DocumentObject* sketch = 0; - App::DocumentObject* support = 0; - if (groove->getTypeId().isDerivedFrom(PartDesign::Groove::getClassTypeId())) { - sketch = static_cast(groove)->Sketch.getValue(); - if (sketch) { - support = static_cast(sketch)->Support.getValue(); - } - } - - //Gui::Command::openCommand("Groove changed"); - ui->grooveAngle->apply(); - std::vector sub; - App::DocumentObject* obj; - parameter->getReferenceAxis(obj, sub); - std::string axis = getPythonStr(obj, sub); - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.ReferenceAxis = %s",name.c_str(),axis.c_str()); - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Midplane = %i",name.c_str(), getMidplane() ? 1 : 0); - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Reversed = %i",name.c_str(), getReversed() ? 1 : 0); - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.recompute()"); - if (groove->isValid()) { - if (sketch) - Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().hide(\"%s\")",sketch->getNameInDocument()); - if (support) - Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().hide(\"%s\")",support->getNameInDocument()); - } - Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().resetEdit()"); - Gui::Command::commitCommand(); - } - -//************************************************************************** -//************************************************************************** -// TaskDialog -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -TaskDlgGrooveParameters::TaskDlgGrooveParameters(ViewProviderGroove *GrooveView) - : TaskDlgSketchBasedParameters(GrooveView) -{ - assert(vp); - parameter = new TaskGrooveParameters(static_cast(vp)); - - Content.push_back(parameter); -} - -TaskDlgGrooveParameters::~TaskDlgGrooveParameters() -{ - -} - -//==== calls from the TaskView =============================================================== - - -void TaskDlgGrooveParameters::open() -{ - // a transaction is already open at creation time of the groove - if (!Gui::Command::hasPendingCommand()) { - QString msg = QObject::tr("Edit groove"); - Gui::Command::openCommand((const char*)msg.toUtf8()); - } -} - -void TaskDlgGrooveParameters::clicked(int) -{ - -} - -bool TaskDlgGrooveParameters::accept() -{ - parameter->apply(); - return true; -} - -bool TaskDlgGrooveParameters::reject() -{ - // get the support and Sketch - PartDesign::Groove* pcGroove = static_cast(vp->getObject()); - Sketcher::SketchObject *pcSketch = 0; - if (pcGroove->Sketch.getValue()) { - pcSketch = static_cast(pcGroove->Sketch.getValue()); - } - - // role back the done things - Gui::Command::abortCommand(); - Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().resetEdit()"); - - // if abort command deleted the object the support is visible again - if (!Gui::Application::Instance->getViewProvider(pcGroove)) { - if (pcSketch && Gui::Application::Instance->getViewProvider(pcSketch)) - Gui::Application::Instance->getViewProvider(pcSketch)->show(); - } - - // Body housekeeping - if (ActivePartObject != NULL) { - // Make the new Tip and the previous solid feature visible again - App::DocumentObject* tip = ActivePartObject->Tip.getValue(); - App::DocumentObject* prev = ActivePartObject->getPrevSolidFeature(); - if (tip != NULL) { - Gui::Application::Instance->getViewProvider(tip)->show(); - if ((tip != prev) && (prev != NULL)) - Gui::Application::Instance->getViewProvider(prev)->show(); - } - } - - return true; -} - - - -#include "moc_TaskGrooveParameters.cpp" diff --git a/src/Mod/PartDesign/Gui/TaskGrooveParameters.h.orig b/src/Mod/PartDesign/Gui/TaskGrooveParameters.h.orig deleted file mode 100644 index edd38bf57..000000000 --- a/src/Mod/PartDesign/Gui/TaskGrooveParameters.h.orig +++ /dev/null @@ -1,117 +0,0 @@ -/****************************************************************************** - * Copyright (c)2012 Jan Rheinlaender * - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file COPYING.LIB. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * - ******************************************************************************/ - - -#ifndef GUI_TASKVIEW_TaskGrooveParameters_H -#define GUI_TASKVIEW_TaskGrooveParameters_H - -#include -#include -#include - -#include "ViewProviderGroove.h" -#include "TaskSketchBasedParameters.h" - -class Ui_TaskGrooveParameters; - -namespace App { -class Property; -} - -namespace Gui { -class ViewProvider; -} - -namespace PartDesignGui { - - - -class TaskGrooveParameters : public TaskSketchBasedParameters -{ - Q_OBJECT - -public: - TaskGrooveParameters(ViewProviderGroove *GrooveView,QWidget *parent = 0); - ~TaskGrooveParameters(); - - void apply(); - -private Q_SLOTS: - void onAngleChanged(double); - void onAxisChanged(int); - void onMidplane(bool); - void onReversed(bool); - -protected: - void onSelectionChanged(const Gui::SelectionChanges& msg) {} - void changeEvent(QEvent *e); - QString getReferenceAxis(void) const; - double getAngle(void) const; - bool getMidplane(void) const; - bool getReversed(void) const; - const bool updateView() const; - -private: - -private: - QWidget* proxy; - Ui_TaskGrooveParameters* ui; -}; - -/// simulation dialog for the TaskView -class TaskDlgGrooveParameters : public TaskDlgSketchBasedParameters -{ - Q_OBJECT - -public: - TaskDlgGrooveParameters(ViewProviderGroove *GrooveView); - ~TaskDlgGrooveParameters(); - - ViewProviderGroove* getGrooveView() const - { return static_cast(vp); } - -public: - /// is called the TaskView when the dialog is opened - virtual void open(); - /// is called by the framework if an button is clicked which has no accept or reject role^M - virtual void clicked(int); - /// is called by the framework if the dialog is accepted (Ok) - virtual bool accept(); - /// is called by the framework if the dialog is rejected (Cancel) - virtual bool reject(); -<<<<<<< 0973b40e8e489ddbf6455e9a2e80b0520f143b58 - virtual bool isAllowedAlterDocument(void) const - { return false; } - - /// returns for Close and Help button - virtual QDialogButtonBox::StandardButtons getStandardButtons(void) const - { return QDialogButtonBox::Ok|QDialogButtonBox::Cancel; } -======= ->>>>>>> Refactored code of SketchBased features to have common code in an abstract superclass - -protected: - TaskGrooveParameters *parameter; -}; - -} //namespace PartDesignGui - -#endif // GUI_TASKVIEW_TASKAPPERANCE_H diff --git a/src/Mod/PartDesign/Gui/TaskLinearPatternParameters.cpp.orig b/src/Mod/PartDesign/Gui/TaskLinearPatternParameters.cpp.orig deleted file mode 100644 index 85cb7d96a..000000000 --- a/src/Mod/PartDesign/Gui/TaskLinearPatternParameters.cpp.orig +++ /dev/null @@ -1,445 +0,0 @@ -/****************************************************************************** - * Copyright (c)2012 Jan Rheinlaender * - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file COPYING.LIB. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * - ******************************************************************************/ - - -#include "PreCompiled.h" - -#ifndef _PreComp_ -# include -# include -#endif - -#include "ui_TaskLinearPatternParameters.h" -#include "TaskLinearPatternParameters.h" -#include "TaskMultiTransformParameters.h" -#include "Workbench.h" -#include "ReferenceSelection.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace PartDesignGui; -using namespace Gui; - -/* TRANSLATOR PartDesignGui::TaskLinearPatternParameters */ - -TaskLinearPatternParameters::TaskLinearPatternParameters(ViewProviderTransformed *TransformedView,QWidget *parent) - : TaskTransformedParameters(TransformedView, parent) -{ - // we need a separate container widget to add all controls to - proxy = new QWidget(this); - ui = new Ui_TaskLinearPatternParameters(); - ui->setupUi(proxy); - QMetaObject::connectSlotsByName(this); - - this->groupLayout()->addWidget(proxy); - - ui->buttonOK->hide(); - ui->checkBoxUpdateView->setEnabled(true); - - selectionMode = none; - - blockUpdate = false; // Hack, sometimes it is NOT false although set to false in Transformed::Transformed()!! - setupUI(); -} - -TaskLinearPatternParameters::TaskLinearPatternParameters(TaskMultiTransformParameters *parentTask, QLayout *layout) - : TaskTransformedParameters(parentTask) -{ - proxy = new QWidget(parentTask); - ui = new Ui_TaskLinearPatternParameters(); - ui->setupUi(proxy); - connect(ui->buttonOK, SIGNAL(pressed()), - parentTask, SLOT(onSubTaskButtonOK())); - QMetaObject::connectSlotsByName(this); - - layout->addWidget(proxy); - - ui->buttonOK->setEnabled(true); - ui->buttonAddFeature->hide(); - ui->buttonRemoveFeature->hide(); - ui->listWidgetFeatures->hide(); - ui->checkBoxUpdateView->hide(); - - selectionMode = none; - - blockUpdate = false; // Hack, sometimes it is NOT false although set to false in Transformed::Transformed()!! - setupUI(); -} - -void TaskLinearPatternParameters::setupUI() -{ - connect(ui->buttonAddFeature, SIGNAL(toggled(bool)), this, SLOT(onButtonAddFeature(bool))); - connect(ui->buttonRemoveFeature, SIGNAL(toggled(bool)), this, SLOT(onButtonRemoveFeature(bool))); - // Create context menu - QAction* action = new QAction(tr("Remove"), this); - ui->listWidgetFeatures->addAction(action); - connect(action, SIGNAL(triggered()), this, SLOT(onFeatureDeleted())); - ui->listWidgetFeatures->setContextMenuPolicy(Qt::ActionsContextMenu); - - updateViewTimer = new QTimer(this); - updateViewTimer->setSingleShot(true); - updateViewTimer->setInterval(getUpdateViewTimeout()); - - connect(updateViewTimer, SIGNAL(timeout()), - this, SLOT(onUpdateViewTimer())); - connect(ui->comboDirection, SIGNAL(activated(int)), - this, SLOT(onDirectionChanged(int))); - connect(ui->checkReverse, SIGNAL(toggled(bool)), - this, SLOT(onCheckReverse(bool))); - connect(ui->spinLength, SIGNAL(valueChanged(double)), - this, SLOT(onLength(double))); - connect(ui->spinOccurrences, SIGNAL(valueChanged(uint)), - this, SLOT(onOccurrences(uint))); - connect(ui->checkBoxUpdateView, SIGNAL(toggled(bool)), - this, SLOT(onUpdateView(bool))); - - // Get the feature data - PartDesign::LinearPattern* pcLinearPattern = static_cast(getObject()); - std::vector originals = pcLinearPattern->Originals.getValues(); - - // Fill data into dialog elements - for (std::vector::const_iterator i = originals.begin(); i != originals.end(); ++i) - { - if ((*i) != NULL) - ui->listWidgetFeatures->addItem(QString::fromLatin1((*i)->getNameInDocument())); - } - // --------------------- - - ui->spinLength->bind(pcLinearPattern->Length); - ui->spinOccurrences->setMaximum(INT_MAX); - ui->spinOccurrences->bind(pcLinearPattern->Occurrences); - - ui->comboDirection->setEnabled(true); - ui->checkReverse->setEnabled(true); - ui->spinLength->blockSignals(true); - ui->spinLength->setEnabled(true); - ui->spinLength->setUnit(Base::Unit::Length); - ui->spinLength->blockSignals(false); - ui->spinOccurrences->setEnabled(true); - - dirLinks.setCombo(*(ui->comboDirection)); - App::DocumentObject* sketch = getSketchObject(); - if (!sketch->isDerivedFrom(Part::Part2DObject::getClassTypeId())) - sketch = 0; - this->fillAxisCombo(dirLinks,static_cast(sketch)); - - updateUI(); - - //show the parts coordinate system axis for selection - App::Part* part = getPartFor(getObject(), false); - if(part) { - auto app_origin = part->getObjectsOfType(App::Origin::getClassTypeId()); - if(!app_origin.empty()) { - ViewProviderOrigin* origin; - origin = static_cast(Gui::Application::Instance->activeDocument()->getViewProvider(app_origin[0])); - origin->setTemporaryVisibilityMode(true, Gui::Application::Instance->activeDocument()); - origin->setTemporaryVisibilityAxis(true); - } - } -} - -void TaskLinearPatternParameters::updateUI() -{ - if (blockUpdate) - return; - blockUpdate = true; - - PartDesign::LinearPattern* pcLinearPattern = static_cast(getObject()); - - bool reverse = pcLinearPattern->Reversed.getValue(); - double length = pcLinearPattern->Length.getValue(); - unsigned occurrences = pcLinearPattern->Occurrences.getValue(); - - if (dirLinks.setCurrentLink(pcLinearPattern->Direction) == -1){ - //failed to set current, because the link isnt in the list yet - dirLinks.addLink(pcLinearPattern->Direction, getRefStr(pcLinearPattern->Direction.getValue(),pcLinearPattern->Direction.getSubValues())); - dirLinks.setCurrentLink(pcLinearPattern->Direction); - } - - // Note: These three lines would trigger onLength(), on Occurrences() and another updateUI() if we - // didn't check for blockUpdate - ui->checkReverse->setChecked(reverse); - ui->spinLength->setValue(length); - ui->spinOccurrences->setValue(occurrences); - - blockUpdate = false; -} - -void TaskLinearPatternParameters::onUpdateViewTimer() -{ - recomputeFeature(); -} - -void TaskLinearPatternParameters::kickUpdateViewTimer() const -{ - updateViewTimer->start(); -} - -void TaskLinearPatternParameters::onSelectionChanged(const Gui::SelectionChanges& msg) -{ - if (msg.Type == Gui::SelectionChanges::AddSelection) { - if (originalSelected(msg)) { - if (selectionMode == addFeature) - ui->listWidgetFeatures->addItem(QString::fromLatin1(msg.pObjectName)); - else - removeItemFromListWidget(ui->listWidgetFeatures, msg.pObjectName); - - exitSelectionMode(); - } else if (selectionMode == reference) { - // Note: ReferenceSelection has already checked the selection for validity - exitSelectionMode(); - std::vector directions; - App::DocumentObject* selObj; - PartDesign::LinearPattern* pcLinearPattern = static_cast(getObject()); - getReferencedSelection(pcLinearPattern, msg, selObj, directions); - pcLinearPattern->Direction.setValue(selObj, directions); - - recomputeFeature(); - updateUI(); - } else if( strstr(msg.pObjectName, App::Part::BaselineTypes[0]) == nullptr || - strstr(msg.pObjectName, App::Part::BaselineTypes[1]) == nullptr || - strstr(msg.pObjectName, App::Part::BaselineTypes[2]) == nullptr) { - - std::vector directions; - App::DocumentObject* selObj; - PartDesign::LinearPattern* pcLinearPattern = static_cast(getObject()); - getReferencedSelection(pcLinearPattern, msg, selObj, directions); - pcLinearPattern->Direction.setValue(selObj, directions); - - recomputeFeature(); - updateUI(); - } - } -} - -void TaskLinearPatternParameters::clearButtons() -{ - ui->buttonAddFeature->setChecked(false); - ui->buttonRemoveFeature->setChecked(false); -} - -void TaskLinearPatternParameters::onCheckReverse(const bool on) { - if (blockUpdate) - return; - PartDesign::LinearPattern* pcLinearPattern = static_cast(getObject()); - pcLinearPattern->Reversed.setValue(on); - - exitSelectionMode(); - kickUpdateViewTimer(); -} - -void TaskLinearPatternParameters::onLength(const double l) { - if (blockUpdate) - return; - PartDesign::LinearPattern* pcLinearPattern = static_cast(getObject()); - pcLinearPattern->Length.setValue(l); - - exitSelectionMode(); - kickUpdateViewTimer(); -} - -void TaskLinearPatternParameters::onOccurrences(const uint n) { - if (blockUpdate) - return; - PartDesign::LinearPattern* pcLinearPattern = static_cast(getObject()); - pcLinearPattern->Occurrences.setValue(n); - - exitSelectionMode(); - kickUpdateViewTimer(); -} - -void TaskLinearPatternParameters::onDirectionChanged(int num) { - if (blockUpdate) - return; - PartDesign::LinearPattern* pcLinearPattern = static_cast(getObject()); - try{ - if(dirLinks.getCurrentLink().getValue() == 0){ - // enter reference selection mode - hideObject(); - showBase(); - selectionMode = reference; - Gui::Selection().clearSelection(); - addReferenceSelectionGate(true, true); - } else { - exitSelectionMode(); - pcLinearPattern->Direction.Paste(dirLinks.getCurrentLink()); - } - } catch (Base::Exception &e) { - QMessageBox::warning(0,tr("Error"),QString::fromAscii(e.what())); - } - - kickUpdateViewTimer(); -} - -void TaskLinearPatternParameters::onUpdateView(bool on) -{ - blockUpdate = !on; - if (on) { - // Do the same like in TaskDlgLinearPatternParameters::accept() but without doCommand - PartDesign::LinearPattern* pcLinearPattern = static_cast(getObject()); - std::vector directions; - App::DocumentObject* obj; - - getDirection(obj, directions); - pcLinearPattern->Direction.setValue(obj,directions); - pcLinearPattern->Reversed.setValue(getReverse()); - pcLinearPattern->Length.setValue(getLength()); - pcLinearPattern->Occurrences.setValue(getOccurrences()); - - recomputeFeature(); - } -} - -void TaskLinearPatternParameters::onFeatureDeleted(void) -{ - PartDesign::Transformed* pcTransformed = getObject(); - std::vector originals = pcTransformed->Originals.getValues(); - originals.erase(originals.begin() + ui->listWidgetFeatures->currentRow()); - pcTransformed->Originals.setValues(originals); - ui->listWidgetFeatures->model()->removeRow(ui->listWidgetFeatures->currentRow()); - recomputeFeature(); -} - -void TaskLinearPatternParameters::getDirection(App::DocumentObject*& obj, std::vector& sub) const -{ - const App::PropertyLinkSub &lnk = dirLinks.getCurrentLink(); - obj = lnk.getValue(); - sub = lnk.getSubValues(); -} - -const bool TaskLinearPatternParameters::getReverse(void) const -{ - return ui->checkReverse->isChecked(); -} - -const double TaskLinearPatternParameters::getLength(void) const -{ - return ui->spinLength->value().getValue(); -} - -const unsigned TaskLinearPatternParameters::getOccurrences(void) const -{ - return ui->spinOccurrences->value(); -} - - -TaskLinearPatternParameters::~TaskLinearPatternParameters() -{ - //hide the parts coordinate system axis for selection - App::Part* part = getPartFor(getObject(), false); - if(part) { - auto app_origin = part->getObjectsOfType(App::Origin::getClassTypeId()); - if(!app_origin.empty()) { - ViewProviderOrigin* origin; - origin = static_cast(Gui::Application::Instance->activeDocument()->getViewProvider(app_origin[0])); - origin->setTemporaryVisibilityMode(false); - } - } - - delete ui; - if (proxy) - delete proxy; -} - -void TaskLinearPatternParameters::changeEvent(QEvent *e) -{ - TaskBox::changeEvent(e); - if (e->type() == QEvent::LanguageChange) { - ui->retranslateUi(proxy); - } -} - -void TaskLinearPatternParameters::apply() -{ - std::string name = TransformedView->getObject()->getNameInDocument(); - - std::vector directions; - App::DocumentObject* obj; - getDirection(obj, directions); - std::string direction = getPythonStr(obj, directions); - if (!direction.empty() && obj) { - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Direction = %s", name.c_str(), direction.c_str()); - } else { - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Direction = None", name.c_str()); - } - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Reversed = %u",name.c_str(),getReverse()); - - ui->spinLength->apply(); - ui->spinOccurrences->apply(); - - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.recompute()"); - if (!TransformedView->getObject()->isValid()) - throw Base::Exception(TransformedView->getObject()->getStatusString()); - Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().resetEdit()"); - Gui::Command::commitCommand(); -} - -//************************************************************************** -//************************************************************************** -// TaskDialog -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -TaskDlgLinearPatternParameters::TaskDlgLinearPatternParameters(ViewProviderLinearPattern *LinearPatternView) - : TaskDlgTransformedParameters(LinearPatternView) -{ - parameter = new TaskLinearPatternParameters(LinearPatternView); - - Content.push_back(parameter); -} - -//==== calls from the TaskView =============================================================== - -bool TaskDlgLinearPatternParameters::accept() -{ - -<<<<<<< a6aea83ec9ef83d52a06178b32175b3e79f73c65 - parameter->apply(); - } - catch (const Base::Exception& e) { - QMessageBox::warning(parameter, tr("Input error"), QString::fromLatin1(e.what())); - return false; - } -======= - parameter->apply(); ->>>>>>> PartDesign: make transform parameter dialogs use common base code with other dialogs - - return TaskDlgTransformedParameters::accept(); -} - -#include "moc_TaskLinearPatternParameters.cpp" diff --git a/src/Mod/PartDesign/Gui/TaskMirroredParameters.cpp.orig b/src/Mod/PartDesign/Gui/TaskMirroredParameters.cpp.orig deleted file mode 100644 index 7116e409b..000000000 --- a/src/Mod/PartDesign/Gui/TaskMirroredParameters.cpp.orig +++ /dev/null @@ -1,361 +0,0 @@ -/****************************************************************************** - * Copyright (c)2012 Jan Rheinlaender * - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file COPYING.LIB. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * - ******************************************************************************/ - - -#include "PreCompiled.h" - -#ifndef _PreComp_ -# include -#endif - -#include "ui_TaskMirroredParameters.h" -#include "TaskMirroredParameters.h" -#include "TaskMultiTransformParameters.h" -#include "Workbench.h" -#include "ReferenceSelection.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace PartDesignGui; -using namespace Gui; - -/* TRANSLATOR PartDesignGui::TaskMirroredParameters */ - -TaskMirroredParameters::TaskMirroredParameters(ViewProviderTransformed *TransformedView, QWidget *parent) - : TaskTransformedParameters(TransformedView, parent) -{ - // we need a separate container widget to add all controls to - proxy = new QWidget(this); - ui = new Ui_TaskMirroredParameters(); - ui->setupUi(proxy); - QMetaObject::connectSlotsByName(this); - - this->groupLayout()->addWidget(proxy); - - ui->buttonOK->hide(); - ui->checkBoxUpdateView->setEnabled(true); - - selectionMode = none; - - blockUpdate = false; // Hack, sometimes it is NOT false although set to false in Transformed::Transformed()!! - setupUI(); -} - -TaskMirroredParameters::TaskMirroredParameters(TaskMultiTransformParameters *parentTask, QLayout *layout) - : TaskTransformedParameters(parentTask) -{ - proxy = new QWidget(parentTask); - ui = new Ui_TaskMirroredParameters(); - ui->setupUi(proxy); - connect(ui->buttonOK, SIGNAL(pressed()), - parentTask, SLOT(onSubTaskButtonOK())); - QMetaObject::connectSlotsByName(this); - - layout->addWidget(proxy); - - ui->buttonOK->setEnabled(true); - ui->buttonAddFeature->hide(); - ui->buttonRemoveFeature->hide(); - ui->listWidgetFeatures->hide(); - ui->checkBoxUpdateView->hide(); - - selectionMode = none; - - blockUpdate = false; // Hack, sometimes it is NOT false although set to false in Transformed::Transformed()!! - setupUI(); -} - -void TaskMirroredParameters::setupUI() -{ - connect(ui->buttonAddFeature, SIGNAL(toggled(bool)), this, SLOT(onButtonAddFeature(bool))); - connect(ui->buttonRemoveFeature, SIGNAL(toggled(bool)), this, SLOT(onButtonRemoveFeature(bool))); - // Create context menu - QAction* action = new QAction(tr("Remove"), this); - ui->listWidgetFeatures->addAction(action); - connect(action, SIGNAL(triggered()), this, SLOT(onFeatureDeleted())); - ui->listWidgetFeatures->setContextMenuPolicy(Qt::ActionsContextMenu); - - connect(ui->comboPlane, SIGNAL(activated(int)), - this, SLOT(onPlaneChanged(int))); - connect(ui->checkBoxUpdateView, SIGNAL(toggled(bool)), - this, SLOT(onUpdateView(bool))); - - // Get the feature data - PartDesign::Mirrored* pcMirrored = static_cast(getObject()); - std::vector originals = pcMirrored->Originals.getValues(); - - // Fill data into dialog elements - for (std::vector::const_iterator i = originals.begin(); i != originals.end(); ++i) - { - if ((*i) != NULL) - ui->listWidgetFeatures->addItem(QString::fromLatin1((*i)->getNameInDocument())); - } - // --------------------- - - this->planeLinks.setCombo(*(ui->comboPlane)); - ui->comboPlane->setEnabled(true); - - - App::DocumentObject* sketch = getSketchObject(); - if (!sketch->isDerivedFrom(Part::Part2DObject::getClassTypeId())) - sketch = 0; - this->fillPlanesCombo(planeLinks,static_cast(sketch)); - - updateUI(); - - //show the parts coordinate system axis for selection - App::Part* part = getPartFor(getObject(), false); - if(part) { - auto app_origin = part->getObjectsOfType(App::Origin::getClassTypeId()); - if(!app_origin.empty()) { - ViewProviderOrigin* origin; - origin = static_cast(Gui::Application::Instance->activeDocument()->getViewProvider(app_origin[0])); - origin->setTemporaryVisibilityMode(true, Gui::Application::Instance->activeDocument()); - origin->setTemporaryVisibilityAxis(true); - } - } -} - -void TaskMirroredParameters::updateUI() -{ - if (blockUpdate) - return; - blockUpdate = true; - - PartDesign::Mirrored* pcMirrored = static_cast(getObject()); - - if (planeLinks.setCurrentLink(pcMirrored->MirrorPlane) == -1){ - //failed to set current, because the link isnt in the list yet - planeLinks.addLink(pcMirrored->MirrorPlane, getRefStr(pcMirrored->MirrorPlane.getValue(),pcMirrored->MirrorPlane.getSubValues())); - planeLinks.setCurrentLink(pcMirrored->MirrorPlane); - } - - blockUpdate = false; -} - -void TaskMirroredParameters::onSelectionChanged(const Gui::SelectionChanges& msg) -{ - if (msg.Type == Gui::SelectionChanges::AddSelection) { - - if (originalSelected(msg)) { - if (selectionMode == addFeature) - ui->listWidgetFeatures->addItem(QString::fromLatin1(msg.pObjectName)); - else - removeItemFromListWidget(ui->listWidgetFeatures, msg.pObjectName); - exitSelectionMode(); - } else if (selectionMode == reference) { - // Note: ReferenceSelection has already checked the selection for validity - exitSelectionMode(); - - std::vector mirrorPlanes; - App::DocumentObject* selObj; - PartDesign::Mirrored* pcMirrored = static_cast(getObject()); - getReferencedSelection(pcMirrored, msg, selObj, mirrorPlanes); - pcMirrored->MirrorPlane.setValue(selObj, mirrorPlanes); - - recomputeFeature(); - updateUI(); - } else if( strstr(msg.pObjectName, App::Part::BaseplaneTypes[0]) == nullptr || - strstr(msg.pObjectName, App::Part::BaseplaneTypes[1]) == nullptr || - strstr(msg.pObjectName, App::Part::BaseplaneTypes[2]) == nullptr) { - - std::vector planes; - App::DocumentObject* selObj; - PartDesign::Mirrored* pcMirrored = static_cast(getObject()); - getReferencedSelection(pcMirrored, msg, selObj, planes); - pcMirrored->MirrorPlane.setValue(selObj, planes); - - recomputeFeature(); - updateUI(); - } - } -} - -void TaskMirroredParameters::clearButtons() -{ - ui->buttonAddFeature->setChecked(false); - ui->buttonRemoveFeature->setChecked(false); -} - -void TaskMirroredParameters::onPlaneChanged(int num) { - if (blockUpdate) - return; - PartDesign::Mirrored* pcMirrored = static_cast(getObject()); - try{ - if(planeLinks.getCurrentLink().getValue() == 0){ - // enter reference selection mode - hideObject(); - showBase(); - selectionMode = reference; - Gui::Selection().clearSelection(); - addReferenceSelectionGate(false, true); - } else { - exitSelectionMode(); - pcMirrored->MirrorPlane.Paste(planeLinks.getCurrentLink()); - } - } catch (Base::Exception &e) { - QMessageBox::warning(0,tr("Error"),QString::fromAscii(e.what())); - } - - recomputeFeature(); -} - -void TaskMirroredParameters::onUpdateView(bool on) -{ - blockUpdate = !on; - if (on) { - // Do the same like in TaskDlgMirroredParameters::accept() but without doCommand - PartDesign::Mirrored* pcMirrored = static_cast(getObject()); - std::vector mirrorPlanes; - App::DocumentObject* obj; - - getMirrorPlane(obj, mirrorPlanes); - pcMirrored->MirrorPlane.setValue(obj,mirrorPlanes); - - recomputeFeature(); - } -} - -void TaskMirroredParameters::onFeatureDeleted(void) -{ - PartDesign::Transformed* pcTransformed = getObject(); - std::vector originals = pcTransformed->Originals.getValues(); - originals.erase(originals.begin() + ui->listWidgetFeatures->currentRow()); - pcTransformed->Originals.setValues(originals); - ui->listWidgetFeatures->model()->removeRow(ui->listWidgetFeatures->currentRow()); - recomputeFeature(); -} - -void TaskMirroredParameters::getMirrorPlane(App::DocumentObject*& obj, std::vector &sub) const -{ - const App::PropertyLinkSub &lnk = planeLinks.getCurrentLink(); - obj = lnk.getValue(); - sub = lnk.getSubValues(); -} - -void TaskMirroredParameters::apply() -{ -} - -TaskMirroredParameters::~TaskMirroredParameters() -{ - //hide the parts coordinate system axis for selection - App::Part* part = getPartFor(getObject(), false); - if(part) { - auto app_origin = part->getObjectsOfType(App::Origin::getClassTypeId()); - if(!app_origin.empty()) { - ViewProviderOrigin* origin; - origin = static_cast(Gui::Application::Instance->activeDocument()->getViewProvider(app_origin[0])); - origin->setTemporaryVisibilityMode(false); - } - } - - - delete ui; - if (proxy) - delete proxy; -} - -void TaskMirroredParameters::changeEvent(QEvent *e) -{ - TaskBox::changeEvent(e); - if (e->type() == QEvent::LanguageChange) { - ui->retranslateUi(proxy); - } -} - -//************************************************************************** -//************************************************************************** -// TaskDialog -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -TaskDlgMirroredParameters::TaskDlgMirroredParameters(ViewProviderMirrored *MirroredView) - : TaskDlgTransformedParameters(MirroredView) -{ - parameter = new TaskMirroredParameters(MirroredView); - - Content.push_back(parameter); -} -//==== calls from the TaskView =============================================================== - -bool TaskDlgMirroredParameters::accept() -{ -<<<<<<< a6aea83ec9ef83d52a06178b32175b3e79f73c65 - std::string name = TransformedView->getObject()->getNameInDocument(); - - try { - // Handle Originals - if (!TaskDlgTransformedParameters::accept()) - return false; - - TaskMirroredParameters* mirrorParameter = static_cast(parameter); - std::vector mirrorPlanes; - App::DocumentObject* obj; - mirrorParameter->getMirrorPlane(obj, mirrorPlanes); - std::string mirrorPlane = getPythonStr(obj, mirrorPlanes); - if (!mirrorPlane.empty() && obj) { - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.MirrorPlane = %s", name.c_str(), mirrorPlane.c_str()); - } else { - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.MirrorPlane = None", name.c_str()); - } - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.recompute()"); - if (!TransformedView->getObject()->isValid()) - throw Base::Exception(TransformedView->getObject()->getStatusString()); - Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().resetEdit()"); - Gui::Command::commitCommand(); - } - catch (const Base::Exception& e) { - QMessageBox::warning(parameter, tr("Input error"), QString::fromLatin1(e.what())); - return false; -======= - std::string name = vp->getObject()->getNameInDocument(); - - TaskMirroredParameters* mirrorParameter = static_cast(parameter); - std::vector mirrorPlanes; - App::DocumentObject* obj; - mirrorParameter->getMirrorPlane(obj, mirrorPlanes); - std::string mirrorPlane = getPythonStr(obj, mirrorPlanes); - if (!mirrorPlane.empty() && obj) { - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.MirrorPlane = %s", name.c_str(), mirrorPlane.c_str()); - } else { - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.MirrorPlane = None", name.c_str()); ->>>>>>> PartDesign: make transform parameter dialogs use common base code with other dialogs - } - - return TaskDlgTransformedParameters::accept(); -} - -#include "moc_TaskMirroredParameters.cpp" diff --git a/src/Mod/PartDesign/Gui/TaskMultiTransformParameters.cpp.orig b/src/Mod/PartDesign/Gui/TaskMultiTransformParameters.cpp.orig deleted file mode 100644 index d25803bf5..000000000 --- a/src/Mod/PartDesign/Gui/TaskMultiTransformParameters.cpp.orig +++ /dev/null @@ -1,512 +0,0 @@ -/****************************************************************************** - * Copyright (c)2012 Jan Rheinlaender * - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file COPYING.LIB. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * - ******************************************************************************/ - - -#include "PreCompiled.h" - -#ifndef _PreComp_ -# include -#endif - -#include "ui_TaskMultiTransformParameters.h" -#include "TaskMultiTransformParameters.h" -#include "TaskMirroredParameters.h" -#include "TaskLinearPatternParameters.h" -#include "TaskPolarPatternParameters.h" -#include "TaskScaledParameters.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -using namespace PartDesignGui; -using namespace Gui; - -/* TRANSLATOR PartDesignGui::TaskMultiTransformParameters */ - -TaskMultiTransformParameters::TaskMultiTransformParameters(ViewProviderTransformed *TransformedView,QWidget *parent) - : TaskTransformedParameters(TransformedView, parent), subTask(NULL) -{ - // we need a separate container widget to add all controls to - proxy = new QWidget(this); - ui = new Ui_TaskMultiTransformParameters(); - ui->setupUi(proxy); - QMetaObject::connectSlotsByName(this); - this->groupLayout()->addWidget(proxy); - - connect(ui->buttonAddFeature, SIGNAL(toggled(bool)), this, SLOT(onButtonAddFeature(bool))); - connect(ui->buttonRemoveFeature, SIGNAL(toggled(bool)), this, SLOT(onButtonRemoveFeature(bool))); - // Create context menu - QAction* action = new QAction(tr("Remove"), this); - ui->listWidgetFeatures->addAction(action); - connect(action, SIGNAL(triggered()), this, SLOT(onFeatureDeleted())); - ui->listWidgetFeatures->setContextMenuPolicy(Qt::ActionsContextMenu); - - // Create a context menu for the listview of transformation features - action = new QAction(tr("Edit"), ui->listTransformFeatures); - action->connect(action, SIGNAL(triggered()), - this, SLOT(onTransformEdit())); - ui->listTransformFeatures->addAction(action); - action = new QAction(tr("Delete"), ui->listTransformFeatures); - action->connect(action, SIGNAL(triggered()), - this, SLOT(onTransformDelete())); - ui->listTransformFeatures->addAction(action); - action = new QAction(tr("Add mirrored transformation"), ui->listTransformFeatures); - action->connect(action, SIGNAL(triggered()), - this, SLOT(onTransformAddMirrored())); - ui->listTransformFeatures->addAction(action); - action = new QAction(tr("Add linear pattern"), ui->listTransformFeatures); - action->connect(action, SIGNAL(triggered()), - this, SLOT(onTransformAddLinearPattern())); - ui->listTransformFeatures->addAction(action); - action = new QAction(tr("Add polar pattern"), ui->listTransformFeatures); - action->connect(action, SIGNAL(triggered()), - this, SLOT(onTransformAddPolarPattern())); - ui->listTransformFeatures->addAction(action); - action = new QAction(tr("Add scaled transformation"), ui->listTransformFeatures); - action->connect(action, SIGNAL(triggered()), - this, SLOT(onTransformAddScaled())); - ui->listTransformFeatures->addAction(action); - action = new QAction(tr("Move up"), ui->listTransformFeatures); - action->connect(action, SIGNAL(triggered()), - this, SLOT(onMoveUp())); - ui->listTransformFeatures->addAction(action); - action = new QAction(tr("Move down"), ui->listTransformFeatures); - action->connect(action, SIGNAL(triggered()), - this, SLOT(onMoveDown())); - ui->listTransformFeatures->addAction(action); - ui->listTransformFeatures->setContextMenuPolicy(Qt::ActionsContextMenu); - connect(ui->checkBoxUpdateView, SIGNAL(toggled(bool)), - this, SLOT(onUpdateView(bool))); - - connect(ui->listTransformFeatures, SIGNAL(activated(QModelIndex)), - this, SLOT(onTransformActivated(QModelIndex))); - - // Get the transformFeatures data - PartDesign::MultiTransform* pcMultiTransform = static_cast(TransformedView->getObject()); - std::vector transformFeatures = pcMultiTransform->Transformations.getValues(); - - // Fill data into dialog elements - ui->listTransformFeatures->setEnabled(true); - ui->listTransformFeatures->clear(); - for (std::vector::const_iterator i = transformFeatures.begin(); i != transformFeatures.end(); i++) - { - if ((*i) != NULL) - ui->listTransformFeatures->addItem(QString::fromLatin1((*i)->Label.getValue())); - } - if (transformFeatures.size() > 0) { - ui->listTransformFeatures->setCurrentRow(0, QItemSelectionModel::ClearAndSelect); - editHint = false; - } else { - ui->listTransformFeatures->addItem(tr("Right-click to add")); - editHint = true; - } - - // Get the Originals data - std::vector originals = pcMultiTransform->Originals.getValues(); - - // Fill data into dialog elements - for (std::vector::const_iterator i = originals.begin(); i != originals.end(); i++) - { - if ((*i) != NULL) - ui->listWidgetFeatures->addItem(QString::fromLatin1((*i)->getNameInDocument())); - } - // --------------------- -} - -void TaskMultiTransformParameters::onSelectionChanged(const Gui::SelectionChanges& msg) -{ - if (originalSelected(msg)) { - if (selectionMode == addFeature) - ui->listWidgetFeatures->addItem(QString::fromLatin1(msg.pObjectName)); - else - removeItemFromListWidget(ui->listWidgetFeatures, msg.pObjectName); - exitSelectionMode(); - } -} - -void TaskMultiTransformParameters::clearButtons() -{ - ui->buttonAddFeature->setChecked(false); - ui->buttonRemoveFeature->setChecked(false); -} - -void TaskMultiTransformParameters::onFeatureDeleted(void) -{ - PartDesign::Transformed* pcTransformed = getObject(); - std::vector originals = pcTransformed->Originals.getValues(); - originals.erase(originals.begin() + ui->listWidgetFeatures->currentRow()); - pcTransformed->Originals.setValues(originals); - ui->listWidgetFeatures->model()->removeRow(ui->listWidgetFeatures->currentRow()); - recomputeFeature(); -} - -void TaskMultiTransformParameters::closeSubTask() -{ - if (subTask) { - exitSelectionMode(); - disconnect(ui->checkBoxUpdateView, 0, subTask, 0); - delete subTask; - subTask = NULL; - } -} - -void TaskMultiTransformParameters::onTransformDelete() -{ - if (editHint) return; // Can't delete the hint... - int row = ui->listTransformFeatures->currentIndex().row(); - PartDesign::MultiTransform* pcMultiTransform = static_cast(TransformedView->getObject()); - std::vector transformFeatures = pcMultiTransform->Transformations.getValues(); - - App::DocumentObject* feature = transformFeatures[row]; - pcMultiTransform->getDocument()->remObject(feature->getNameInDocument()); - closeSubTask(); - - transformFeatures.erase(transformFeatures.begin() + row); - pcMultiTransform->Transformations.setValues(transformFeatures); - // Note: When the last transformation is deleted, recomputeFeature does nothing, because Transformed::execute() - // says: "No transformations defined, exit silently" - recomputeFeature(); - - ui->listTransformFeatures->model()->removeRow(row); - ui->listTransformFeatures->setCurrentRow(0, QItemSelectionModel::ClearAndSelect); -} - -void TaskMultiTransformParameters::onTransformEdit() -{ - if (editHint) return; // Can't edit the hint... - closeSubTask(); // For example if user is editing one subTask and then double-clicks on another without OK'ing first - ui->listTransformFeatures->currentItem()->setSelected(true); - int row = ui->listTransformFeatures->currentIndex().row(); - PartDesign::MultiTransform* pcMultiTransform = static_cast(TransformedView->getObject()); - std::vector transformFeatures = pcMultiTransform->Transformations.getValues(); - - subFeature = static_cast(transformFeatures[row]); - if (transformFeatures[row]->getTypeId() == PartDesign::Mirrored::getClassTypeId()) - subTask = new TaskMirroredParameters(this, ui->verticalLayout); - else if (transformFeatures[row]->getTypeId() == PartDesign::LinearPattern::getClassTypeId()) - subTask = new TaskLinearPatternParameters(this, ui->verticalLayout); - else if (transformFeatures[row]->getTypeId() == PartDesign::PolarPattern::getClassTypeId()) - subTask = new TaskPolarPatternParameters(this, ui->verticalLayout); - else if (transformFeatures[row]->getTypeId() == PartDesign::Scaled::getClassTypeId()) - subTask = new TaskScaledParameters(this, ui->verticalLayout); - else - return; // TODO: Show an error? - - connect(ui->checkBoxUpdateView, SIGNAL(toggled(bool)), - subTask, SLOT(onUpdateView(bool))); -} - -void TaskMultiTransformParameters::onTransformActivated(const QModelIndex& index) { - onTransformEdit(); -} - -void TaskMultiTransformParameters::onTransformAddMirrored() -{ - closeSubTask(); - std::string newFeatName = TransformedView->getObject()->getDocument()->getUniqueObjectName("Mirrored"); - - Gui::Command::openCommand("Mirrored"); - Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().addObject(\"PartDesign::Mirrored\",\"%s\")",newFeatName.c_str()); - //Gui::Command::updateActive(); - App::DocumentObject* sketch = getSketchObject(); - if (sketch) - Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().%s.MirrorPlane = (App.activeDocument().%s, [\"V_Axis\"])", - newFeatName.c_str(), sketch->getNameInDocument()); - - finishAdd(newFeatName); -} - -void TaskMultiTransformParameters::onTransformAddLinearPattern() -{ - closeSubTask(); - std::string newFeatName = TransformedView->getObject()->getDocument()->getUniqueObjectName("LinearPattern"); - - Gui::Command::openCommand("LinearPattern"); - Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().addObject(\"PartDesign::LinearPattern\",\"%s\")",newFeatName.c_str()); - //Gui::Command::updateActive(); - App::DocumentObject* sketch = getSketchObject(); - if (sketch) - Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().%s.Direction = (App.activeDocument().%s, [\"H_Axis\"])", - newFeatName.c_str(), sketch->getNameInDocument()); - Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().%s.Length = 100", newFeatName.c_str()); - Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().%s.Occurrences = 2", newFeatName.c_str()); - - finishAdd(newFeatName); -} - -void TaskMultiTransformParameters::onTransformAddPolarPattern() -{ - closeSubTask(); - std::string newFeatName = TransformedView->getObject()->getDocument()->getUniqueObjectName("PolarPattern"); - - Gui::Command::openCommand("PolarPattern"); - Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().addObject(\"PartDesign::PolarPattern\",\"%s\")",newFeatName.c_str()); - //Gui::Command::updateActive(); - App::DocumentObject* sketch = getSketchObject(); - if (sketch) - Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().%s.Axis = (App.activeDocument().%s, [\"N_Axis\"])", - newFeatName.c_str(), sketch->getNameInDocument()); - Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().%s.Angle = 360", newFeatName.c_str()); - Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().%s.Occurrences = 2", newFeatName.c_str()); - - finishAdd(newFeatName); -} - -void TaskMultiTransformParameters::onTransformAddScaled() -{ - closeSubTask(); - std::string newFeatName = TransformedView->getObject()->getDocument()->getUniqueObjectName("Scaled"); - - Gui::Command::openCommand("Scaled"); - Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().addObject(\"PartDesign::Scaled\",\"%s\")",newFeatName.c_str()); - //Gui::Command::updateActive(); - Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().%s.Factor = 2", newFeatName.c_str()); - Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().%s.Occurrences = 2", newFeatName.c_str()); - - finishAdd(newFeatName); -} - -void TaskMultiTransformParameters::finishAdd(std::string &newFeatName) -{ - //Gui::Command::updateActive(); - //Gui::Command::copyVisual(newFeatName.c_str(), "ShapeColor", getOriginals().front()->getNameInDocument().c_str()); - //Gui::Command::copyVisual(newFeatName.c_str(), "DisplayMode", getOriginals().front()->getNameInDocument().c_str()); - - PartDesign::MultiTransform* pcMultiTransform = static_cast(TransformedView->getObject()); - if (editHint) { - // Remove hint, first feature is being added - ui->listTransformFeatures->model()->removeRow(0); - } - int row = ui->listTransformFeatures->currentIndex().row(); - if (row < 0) { - // Happens when first row (first transformation) is created - // Hide all the originals now (hiding them in Command.cpp presents the user with an empty screen!) - hideBase(); - } - - // Insert new transformation after the selected row - // This means that in order to insert at the beginning, the user has to use "Move Up" in the menu - App::DocumentObject* newFeature = pcMultiTransform->getDocument()->getObject(newFeatName.c_str()); - std::vector transformFeatures = pcMultiTransform->Transformations.getValues(); - if (row == ui->listTransformFeatures->model()->rowCount() - 1) { - // Note: Inserts always happen before the specified iterator so in order to append at the - // end we need to use push_back() and append() - transformFeatures.push_back(newFeature); - ui->listTransformFeatures->addItem(QString::fromLatin1(newFeature->Label.getValue())); - ui->listTransformFeatures->setCurrentRow(row+1, QItemSelectionModel::ClearAndSelect); - } else { - // Note: The feature tree always seems to append to the end, no matter what we say here - transformFeatures.insert(transformFeatures.begin() + row + 1, newFeature); - ui->listTransformFeatures->insertItem(row + 1, QString::fromLatin1(newFeature->Label.getValue())); - ui->listTransformFeatures->setCurrentRow(row + 1, QItemSelectionModel::ClearAndSelect); - } - pcMultiTransform->Transformations.setValues(transformFeatures); - - recomputeFeature(); - - // Set state to hidden - only the MultiTransform should be visible - Gui::Command::doCommand( - Gui::Command::Doc,"Gui.activeDocument().getObject(\"%s\").Visibility=False", newFeatName.c_str()); - editHint = false; - - onTransformEdit(); -} - -void TaskMultiTransformParameters::moveTransformFeature(const int increment) -{ - int row = ui->listTransformFeatures->currentIndex().row(); - PartDesign::MultiTransform* pcMultiTransform = static_cast(TransformedView->getObject()); - std::vector transformFeatures = pcMultiTransform->Transformations.getValues(); - - App::DocumentObject* feature = transformFeatures[row]; - transformFeatures.erase(transformFeatures.begin() + row); - QListWidgetItem* item = new QListWidgetItem(*(ui->listTransformFeatures->item(row))); - ui->listTransformFeatures->model()->removeRow(row); - // After this operation, if we were to insert at index row again, things will remain unchanged - - row += increment; - - if (row < 0) - row = 0; - - if (row >= ui->listTransformFeatures->model()->rowCount()) { - // Note: Inserts always happen before the specified iterator so in order to append at the - // end we need to use push_back() and append() - transformFeatures.push_back(feature); - ui->listTransformFeatures->addItem(item); - ui->listTransformFeatures->setCurrentRow(row, QItemSelectionModel::ClearAndSelect); - } else { - transformFeatures.insert(transformFeatures.begin() + row, feature); - ui->listTransformFeatures->insertItem(row, item); - ui->listTransformFeatures->setCurrentRow(row, QItemSelectionModel::ClearAndSelect); - } - - pcMultiTransform->Transformations.setValues(transformFeatures); - recomputeFeature(); -} - -void TaskMultiTransformParameters::onMoveUp() -{ - moveTransformFeature(-1); -} - -void TaskMultiTransformParameters::onMoveDown() -{ - moveTransformFeature(+1); -} - -void TaskMultiTransformParameters::onSubTaskButtonOK() { - closeSubTask(); -} - -void TaskMultiTransformParameters::onUpdateView(bool on) -{ - blockUpdate = !on; - if (on) - recomputeFeature(); -} - -const std::vector TaskMultiTransformParameters::getTransformFeatures(void) const -{ - PartDesign::MultiTransform* pcMultiTransform = static_cast(TransformedView->getObject()); - return pcMultiTransform->Transformations.getValues(); -} - -void TaskMultiTransformParameters::apply() -{ -} - -TaskMultiTransformParameters::~TaskMultiTransformParameters() -{ - closeSubTask(); - delete ui; - if (proxy) - delete proxy; -} - -void TaskMultiTransformParameters::changeEvent(QEvent *e) -{ - TaskBox::changeEvent(e); - if (e->type() == QEvent::LanguageChange) { - ui->retranslateUi(proxy); - } -} - -//************************************************************************** -//************************************************************************** -// TaskDialog -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -TaskDlgMultiTransformParameters::TaskDlgMultiTransformParameters(ViewProviderMultiTransform *MultiTransformView) - : TaskDlgTransformedParameters(MultiTransformView) -{ - parameter = new TaskMultiTransformParameters(MultiTransformView); - - Content.push_back(parameter); -} -//==== calls from the TaskView =============================================================== - -bool TaskDlgMultiTransformParameters::accept() -{ -<<<<<<< a6aea83ec9ef83d52a06178b32175b3e79f73c65 - std::string name = TransformedView->getObject()->getNameInDocument(); - - try { - //Gui::Command::openCommand("MultiTransform changed"); - // Handle Originals - if (!TaskDlgTransformedParameters::accept()) - return false; - - TaskMultiTransformParameters* mtParameter = static_cast(parameter); - std::vector transformFeatures = mtParameter->getTransformFeatures(); - std::stringstream str; - str << "App.ActiveDocument." << name.c_str() << ".Transformations = ["; - for (std::vector::const_iterator it = transformFeatures.begin(); it != transformFeatures.end(); it++) - { - if ((*it) != NULL) - str << "App.ActiveDocument." << (*it)->getNameInDocument() << ","; - } - str << "]"; - Gui::Command::runCommand(Gui::Command::Doc,str.str().c_str()); - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.recompute()"); - if (!TransformedView->getObject()->isValid()) - throw Base::Exception(TransformedView->getObject()->getStatusString()); - Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().resetEdit()"); - Gui::Command::commitCommand(); - } - catch (const Base::Exception& e) { - QMessageBox::warning(parameter, tr("Input error"), QString::fromLatin1(e.what())); - return false; -======= - std::string name = vp->getObject()->getNameInDocument(); - - // Set up transformations - TaskMultiTransformParameters* mtParameter = static_cast(parameter); - std::vector transformFeatures = mtParameter->getTransformFeatures(); - std::stringstream str; - str << "App.ActiveDocument." << name.c_str() << ".Transformations = ["; - for (std::vector::const_iterator it = transformFeatures.begin(); it != transformFeatures.end(); it++) - { - if ((*it) != NULL) - str << "App.ActiveDocument." << (*it)->getNameInDocument() << ","; ->>>>>>> PartDesign: make transform parameter dialogs use common base code with other dialogs - } - str << "]"; - Gui::Command::runCommand(Gui::Command::Doc,str.str().c_str()); - - return TaskDlgFeatureParameters::accept (); -} - -bool TaskDlgMultiTransformParameters::reject() -{ - // Get objects before view is invalidated - // For the same reason we can't delegate showing the originals to TaskDlgTransformedParameters::reject() - PartDesign::MultiTransform* pcMultiTransform = static_cast(vp->getObject()); - std::vector transformFeatures = pcMultiTransform->Transformations.getValues(); - - // Delete the transformation features - must happen before abortCommand()! - for (std::vector::const_iterator it = transformFeatures.begin(); it != transformFeatures.end(); ++it) - { - if ((*it) != NULL) - Gui::Command::doCommand( - Gui::Command::Doc,"App.ActiveDocument.removeObject(\"%s\")", (*it)->getNameInDocument()); - } - - return TaskDlgTransformedParameters::reject(); -} - -#include "moc_TaskMultiTransformParameters.cpp" diff --git a/src/Mod/PartDesign/Gui/TaskPadParameters.cpp.orig b/src/Mod/PartDesign/Gui/TaskPadParameters.cpp.orig deleted file mode 100644 index ec9d7c4ed..000000000 --- a/src/Mod/PartDesign/Gui/TaskPadParameters.cpp.orig +++ /dev/null @@ -1,507 +0,0 @@ -/*************************************************************************** - * Copyright (c) 2011 Juergen Riegel * - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file COPYING.LIB. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * - ***************************************************************************/ - - -#include "PreCompiled.h" - -#ifndef _PreComp_ -# include -# include -# include -# include -# include -#endif - -#include "ui_TaskPadParameters.h" -#include "TaskPadParameters.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "TaskSketchBasedParameters.h" -#include "ReferenceSelection.h" -#include "Workbench.h" - -using namespace PartDesignGui; -using namespace Gui; - -/* TRANSLATOR PartDesignGui::TaskPadParameters */ - -TaskPadParameters::TaskPadParameters(ViewProviderPad *PadView,bool newObj, QWidget *parent) - : TaskSketchBasedParameters(PadView, parent, "PartDesign_Pad",tr("Pad parameters")) -{ - // we need a separate container widget to add all controls to - proxy = new QWidget(this); - ui = new Ui_TaskPadParameters(); - ui->setupUi(proxy); - QMetaObject::connectSlotsByName(this); - - connect(ui->lengthEdit, SIGNAL(valueChanged(double)), - this, SLOT(onLengthChanged(double))); - connect(ui->checkBoxMidplane, SIGNAL(toggled(bool)), - this, SLOT(onMidplane(bool))); - connect(ui->checkBoxReversed, SIGNAL(toggled(bool)), - this, SLOT(onReversed(bool))); - connect(ui->lengthEdit2, SIGNAL(valueChanged(double)), - this, SLOT(onLength2Changed(double))); - connect(ui->spinOffset, SIGNAL(valueChanged(double)), - this, SLOT(onOffsetChanged(double))); - connect(ui->changeMode, SIGNAL(currentIndexChanged(int)), - this, SLOT(onModeChanged(int))); - connect(ui->buttonFace, SIGNAL(clicked()), - this, SLOT(onButtonFace())); - connect(ui->lineFaceName, SIGNAL(textEdited(QString)), - this, SLOT(onFaceName(QString))); - connect(ui->checkBoxUpdateView, SIGNAL(toggled(bool)), - this, SLOT(onUpdateView(bool))); - - this->groupLayout()->addWidget(proxy); - - // Temporarily prevent unnecessary feature recomputes - ui->lengthEdit->blockSignals(true); - ui->lengthEdit2->blockSignals(true); - ui->spinOffset->blockSignals(true); - ui->checkBoxMidplane->blockSignals(true); - ui->checkBoxReversed->blockSignals(true); - ui->buttonFace->blockSignals(true); - ui->lineFaceName->blockSignals(true); - ui->changeMode->blockSignals(true); - - // set the history path - ui->lengthEdit->setParamGrpPath(QByteArray("User parameter:BaseApp/History/PadLength")); - ui->lengthEdit2->setParamGrpPath(QByteArray("User parameter:BaseApp/History/PadLength2")); - - // Get the feature data - PartDesign::Pad* pcPad = static_cast(vp->getObject()); - Base::Quantity l = pcPad->Length.getQuantityValue(); - bool midplane = pcPad->Midplane.getValue(); - bool reversed = pcPad->Reversed.getValue(); - Base::Quantity l2 = pcPad->Length2.getQuantityValue(); - double off = pcPad->Offset.getValue(); - int index = pcPad->Type.getValue(); // must extract value here, clear() kills it! - App::DocumentObject* obj = pcPad->UpToFace.getValue(); - std::vector subStrings = pcPad->UpToFace.getSubValues(); - std::string upToFace; - int faceId = -1; - if ((obj != NULL) && !subStrings.empty()) { - upToFace = subStrings.front(); - if (upToFace.substr(0,4) == "Face") - faceId = std::atoi(&upToFace[4]); - } - - // Fill data into dialog elements - ui->lengthEdit->setMinimum(0); - ui->lengthEdit->setMaximum(INT_MAX); - ui->lengthEdit->setValue(l); - ui->lengthEdit2->setMinimum(0); - ui->lengthEdit2->setMaximum(INT_MAX); - ui->lengthEdit2->setValue(l2); - ui->spinOffset->setMaximum(INT_MAX); - ui->spinOffset->setMinimum(-INT_MAX); - ui->spinOffset->setValue(off); - - // Bind input fields to properties - ui->lengthEdit->bind(pcPad->Length); - ui->lengthEdit2->bind(pcPad->Length2); - ui->checkBoxMidplane->setChecked(midplane); - // According to bug #0000521 the reversed option - // shouldn't be de-activated if the pad has a support face - ui->checkBoxReversed->setChecked(reversed); - if ((obj != NULL) && PartDesign::Feature::isDatum(obj)) - ui->lineFaceName->setText(QString::fromAscii(obj->getNameInDocument())); - else if (faceId >= 0) - ui->lineFaceName->setText(QString::fromAscii(obj->getNameInDocument()) + QString::fromAscii(":") + tr("Face") + - QString::number(faceId)); - else - ui->lineFaceName->setText(tr("No face selected")); - ui->lineFaceName->setProperty("FaceName", QByteArray(upToFace.c_str())); - ui->changeMode->clear(); - ui->changeMode->insertItem(0, tr("Dimension")); - ui->changeMode->insertItem(1, tr("To last")); - ui->changeMode->insertItem(2, tr("To first")); - ui->changeMode->insertItem(3, tr("Up to face")); - ui->changeMode->insertItem(4, tr("Two dimensions")); - ui->changeMode->setCurrentIndex(index); - - // activate and de-activate dialog elements as appropriate - ui->lengthEdit->blockSignals(false); - ui->lengthEdit2->blockSignals(false); - ui->spinOffset->blockSignals(false); - ui->checkBoxMidplane->blockSignals(false); - ui->checkBoxReversed->blockSignals(false); - ui->buttonFace->blockSignals(false); - ui->lineFaceName->blockSignals(false); - ui->changeMode->blockSignals(false); - updateUI(index); - - // if it is a newly created object use the last value of the history - if(newObj){ - ui->lengthEdit->setToLastUsedValue(); - ui->lengthEdit->selectNumber(); - ui->lengthEdit2->setToLastUsedValue(); - ui->lengthEdit2->selectNumber(); - } -} - -void TaskPadParameters::updateUI(int index) -{ - if (index == 0) { // dimension - ui->lengthEdit->setVisible(true); - ui->lengthEdit->setEnabled(true); - ui->lengthEdit->selectNumber(); - ui->labelLength->setVisible(true); - ui->spinOffset->setVisible(false); - ui->spinOffset->setEnabled(false); - ui->labelOffset->setVisible(false); - // Make sure that the spin box has the focus to get key events - // Calling setFocus() directly doesn't work because the spin box is not - // yet visible. - QMetaObject::invokeMethod(ui->lengthEdit, "setFocus", Qt::QueuedConnection); - ui->checkBoxMidplane->setEnabled(true); - // Reverse only makes sense if Midplane is not true - ui->checkBoxReversed->setEnabled(!ui->checkBoxMidplane->isChecked()); - ui->labelLength2->setVisible(false); - ui->lengthEdit2->setVisible(false); - ui->lengthEdit2->setEnabled(false); - ui->buttonFace->setEnabled(false); - ui->lineFaceName->setEnabled(false); - onButtonFace(false); - } else if (index == 1 || index == 2) { // up to first/last - ui->lengthEdit->setVisible(false); - ui->lengthEdit->setEnabled(false); - ui->labelLength->setVisible(false); - ui->spinOffset->setVisible(true); - ui->spinOffset->setEnabled(true); - ui->labelOffset->setVisible(true); - ui->checkBoxMidplane->setEnabled(false); - ui->checkBoxReversed->setEnabled(true); - ui->labelLength2->setVisible(false); - ui->lengthEdit2->setVisible(false); - ui->lengthEdit2->setEnabled(false); - ui->buttonFace->setEnabled(false); - ui->lineFaceName->setEnabled(false); - onButtonFace(false); - } else if (index == 3) { // up to face - ui->lengthEdit->setVisible(false); - ui->lengthEdit->setEnabled(false); - ui->labelLength->setVisible(false); - ui->spinOffset->setVisible(true); - ui->spinOffset->setEnabled(true); - ui->labelOffset->setVisible(true); - ui->checkBoxMidplane->setEnabled(false); - ui->checkBoxReversed->setEnabled(false); - ui->labelLength2->setVisible(false); - ui->lengthEdit2->setVisible(false); - ui->lengthEdit2->setEnabled(false); - ui->buttonFace->setEnabled(true); - ui->lineFaceName->setEnabled(true); - QMetaObject::invokeMethod(ui->lineFaceName, "setFocus", Qt::QueuedConnection); - // Go into reference selection mode if no face has been selected yet - if (ui->lineFaceName->text().isEmpty() || (ui->lineFaceName->text() == tr("No face selected"))) - onButtonFace(true); - } else { // two dimensions - ui->lengthEdit->setEnabled(true); - ui->lengthEdit->setVisible(true); - ui->lengthEdit->selectNumber(); - QMetaObject::invokeMethod(ui->lengthEdit, "setFocus", Qt::QueuedConnection); - ui->labelLength->setVisible(true); - ui->spinOffset->setVisible(false); - ui->spinOffset->setEnabled(false); - ui->labelOffset->setVisible(false); - ui->checkBoxMidplane->setEnabled(false); - ui->checkBoxReversed->setEnabled(false); - ui->labelLength2->setVisible(true); - ui->lengthEdit2->setVisible(true); - ui->lengthEdit2->setEnabled(true); - ui->buttonFace->setEnabled(false); - ui->lineFaceName->setEnabled(false); - onButtonFace(false); - } -} - -void TaskPadParameters::onSelectionChanged(const Gui::SelectionChanges& msg) -{ - if (msg.Type == Gui::SelectionChanges::AddSelection) { - QString refText = onAddSelection(msg); - if (refText.length() != 0) { - ui->lineFaceName->blockSignals(true); - ui->lineFaceName->setText(refText); - ui->lineFaceName->setProperty("FaceName", QByteArray(msg.pSubName)); - ui->lineFaceName->blockSignals(false); - // Turn off reference selection mode - onButtonFace(false); - } else { - ui->lineFaceName->blockSignals(true); - ui->lineFaceName->setText(tr("No face selected")); - ui->lineFaceName->setProperty("FaceName", QByteArray()); - ui->lineFaceName->blockSignals(false); - } - } - - else if (msg.Type == Gui::SelectionChanges::ClrSelection) { - ui->lineFaceName->blockSignals(true); - ui->lineFaceName->setText(tr("")); - ui->lineFaceName->setProperty("FaceName", QByteArray()); - ui->lineFaceName->blockSignals(false); - } -} - -void TaskPadParameters::onLengthChanged(double len) -{ - PartDesign::Pad* pcPad = static_cast(vp->getObject()); - pcPad->Length.setValue(len); - recomputeFeature(); -} - -void TaskPadParameters::onMidplane(bool on) -{ - PartDesign::Pad* pcPad = static_cast(vp->getObject()); - pcPad->Midplane.setValue(on); - ui->checkBoxReversed->setEnabled(!on); - recomputeFeature(); -} - -void TaskPadParameters::onReversed(bool on) -{ - PartDesign::Pad* pcPad = static_cast(vp->getObject()); - pcPad->Reversed.setValue(on); - recomputeFeature(); -} - -void TaskPadParameters::onLength2Changed(double len) -{ - PartDesign::Pad* pcPad = static_cast(vp->getObject()); - pcPad->Length2.setValue(len); - recomputeFeature(); -} - -void TaskPadParameters::onOffsetChanged(double len) -{ - PartDesign::Pad* pcPad = static_cast(vp->getObject()); - pcPad->Offset.setValue(len); - recomputeFeature(); -} - -void TaskPadParameters::onModeChanged(int index) -{ - PartDesign::Pad* pcPad = static_cast(vp->getObject()); - - switch (index) { - case 0: - pcPad->Type.setValue("Length"); - // Avoid error message - if (ui->lengthEdit->value() < Precision::Confusion()) - ui->lengthEdit->setValue(5.0); - break; - case 1: pcPad->Type.setValue("UpToLast"); break; - case 2: pcPad->Type.setValue("UpToFirst"); break; - case 3: pcPad->Type.setValue("UpToFace"); break; - default: pcPad->Type.setValue("TwoLengths"); - } - - updateUI(index); - recomputeFeature(); -} - -void TaskPadParameters::onButtonFace(const bool pressed) -{ - TaskSketchBasedParameters::onSelectReference(pressed, false, true, false); - - // Update button if onButtonFace() is called explicitly - ui->buttonFace->setChecked(pressed); -} - -void TaskPadParameters::onFaceName(const QString& text) -{ - ui->lineFaceName->setProperty("FaceName", TaskSketchBasedParameters::onFaceName(text)); -} - -double TaskPadParameters::getLength(void) const -{ - return ui->lengthEdit->value().getValue(); -} - -bool TaskPadParameters::getReversed(void) const -{ - return ui->checkBoxReversed->isChecked(); -} - -bool TaskPadParameters::getMidplane(void) const -{ - return ui->checkBoxMidplane->isChecked(); -} - -double TaskPadParameters::getLength2(void) const -{ - return ui->lengthEdit2->value().getValue(); -} - -double TaskPadParameters::getOffset(void) const -{ - return ui->spinOffset->value(); -} - -int TaskPadParameters::getMode(void) const -{ - return ui->changeMode->currentIndex(); -} - -QString TaskPadParameters::getFaceName(void) const -{ - if (getMode() == 3) { - QString faceName = ui->lineFaceName->property("FaceName").toString(); - if (!faceName.isEmpty()) { - return getFaceReference(ui->lineFaceName->text(), faceName); - } - } - return QString(); -} - -TaskPadParameters::~TaskPadParameters() -{ - delete ui; -} - -void TaskPadParameters::changeEvent(QEvent *e) -{ - TaskBox::changeEvent(e); - if (e->type() == QEvent::LanguageChange) { - ui->lengthEdit->blockSignals(true); - ui->lengthEdit2->blockSignals(true); - ui->spinOffset->blockSignals(true); - ui->lineFaceName->blockSignals(true); - ui->changeMode->blockSignals(true); - int index = ui->changeMode->currentIndex(); - ui->retranslateUi(proxy); - ui->changeMode->clear(); - ui->changeMode->addItem(tr("Dimension")); - ui->changeMode->addItem(tr("To last")); - ui->changeMode->addItem(tr("To first")); - ui->changeMode->addItem(tr("Up to face")); - ui->changeMode->addItem(tr("Two dimensions")); - ui->changeMode->setCurrentIndex(index); - - QStringList parts = ui->lineFaceName->text().split(QChar::fromAscii(':')); - QByteArray upToFace = ui->lineFaceName->property("FaceName").toByteArray(); - int faceId = -1; - bool ok = false; - if (upToFace.indexOf("Face") == 0) { - faceId = upToFace.remove(0,4).toInt(&ok); - } -#if QT_VERSION >= 0x040700 - ui->lineFaceName->setPlaceholderText(tr("No face selected")); -#endif - ui->lineFaceName->setText(ok ? - parts[0] + QString::fromAscii(":") + tr("Face") + QString::number(faceId) : - QString()); - ui->lengthEdit->blockSignals(false); - ui->lengthEdit2->blockSignals(false); - ui->spinOffset->blockSignals(false); - ui->lineFaceName->blockSignals(false); - ui->changeMode->blockSignals(false); - } -} - -void TaskPadParameters::saveHistory(void) -{ - // save the user values to history - ui->lengthEdit->pushToHistory(); - ui->lengthEdit2->pushToHistory(); -} - -void TaskPadParameters::apply() -{ - std::string name = vp->getObject()->getNameInDocument(); - const char * cname = name.c_str(); - - ui->lengthEdit->apply(); - - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Reversed = %i",cname,getReversed()?1:0); - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Midplane = %i",cname,getMidplane()?1:0); - - ui->lengthEdit2->apply(); - - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Type = %u",cname,getMode()); - QString facename = getFaceName(); - - if (!facename.isEmpty()) { - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.UpToFace = %s", - cname, facename.toLatin1().data()); - } else { - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.UpToFace = None", cname); - } - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Offset = %f", name.c_str(), getOffset()); -} - -//************************************************************************** -//************************************************************************** -// TaskDialog -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -TaskDlgPadParameters::TaskDlgPadParameters(ViewProviderPad *PadView,bool newObj) - : TaskDlgSketchBasedParameters(PadView) -{ - assert(PadView); - parameter = new TaskPadParameters(static_cast(PadView)); - - Content.push_back(parameter); -} - -TaskDlgPadParameters::~TaskDlgPadParameters() -{ - -} - -//==== calls from the TaskView =============================================================== - -bool TaskDlgPadParameters::accept() -{ - // save the history - parameter->saveHistory(); - parameter->apply(); - -<<<<<<< b551f892abed242e90afa77240bbdd7dcf7fc45c - try { - //Gui::Command::openCommand("Pad changed"); - parameter->apply(); - } - catch (const Base::Exception& e) { - QMessageBox::warning(parameter, tr("Input error"), QString::fromLatin1(e.what())); - return false; - } - - return true; -======= - return TaskDlgSketchBasedParameters::accept(); ->>>>>>> PartDesignGui: Make DressUp and SketchSupport propertie dialogs use common accept() structure -} - - -#include "moc_TaskPadParameters.cpp" diff --git a/src/Mod/PartDesign/Gui/TaskPadParameters.h.orig b/src/Mod/PartDesign/Gui/TaskPadParameters.h.orig deleted file mode 100644 index 2d9caf073..000000000 --- a/src/Mod/PartDesign/Gui/TaskPadParameters.h.orig +++ /dev/null @@ -1,121 +0,0 @@ -/*************************************************************************** - * Copyright (c) 2011 Juergen Riegel * - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file COPYING.LIB. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * - ***************************************************************************/ - - -#ifndef GUI_TASKVIEW_TaskPadParameters_H -#define GUI_TASKVIEW_TaskPadParameters_H - -#include -#include -#include - -#include "TaskSketchBasedParameters.h" -#include "ViewProviderPad.h" - -class Ui_TaskPadParameters; - -namespace App { -class Property; -} - -namespace Gui { -class ViewProvider; -} - -namespace PartDesignGui { - - - -class TaskPadParameters : public TaskSketchBasedParameters -{ - Q_OBJECT - -public: - TaskPadParameters(ViewProviderPad *PadView,bool newObj=false,QWidget *parent = 0); - ~TaskPadParameters(); - - const bool updateView() const; - void saveHistory(void); - void apply(); - -private Q_SLOTS: - void onLengthChanged(double); - void onMidplane(bool); - void onReversed(bool); - void onLength2Changed(double); - void onModeChanged(int); - void onButtonFace(const bool pressed = true); - void onFaceName(const QString& text); - -protected: - void changeEvent(QEvent *e); - -private: - int getMode(void) const; - double getLength(void) const; - double getLength2(void) const; - bool getReversed(void) const; - bool getMidplane(void) const; - QByteArray getFaceName(void) const; - void onSelectionChanged(const Gui::SelectionChanges& msg); - void updateUI(int index); - -private: - QWidget* proxy; - Ui_TaskPadParameters* ui; -}; - -/// simulation dialog for the TaskView -class TaskDlgPadParameters : public TaskDlgSketchBasedParameters -{ - Q_OBJECT - -public: - TaskDlgPadParameters(ViewProviderPad *PadView,bool newObj=false); - ~TaskDlgPadParameters(); - - ViewProviderPad* getPadView() const - { return static_cast(vp); } - - -public: - /// is called by the framework if the dialog is accepted (Ok) - virtual bool accept(); - /// is called by the framework if the dialog is rejected (Cancel) -<<<<<<< 0973b40e8e489ddbf6455e9a2e80b0520f143b58 - virtual bool reject(); - virtual bool isAllowedAlterDocument(void) const - { return false; } - - /// returns for Close and Help button - virtual QDialogButtonBox::StandardButtons getStandardButtons(void) const - { return QDialogButtonBox::Ok|QDialogButtonBox::Cancel; } -======= ->>>>>>> Refactored code of SketchBased features to have common code in an abstract superclass - -protected: - TaskPadParameters *parameter; -}; - -} //namespace PartDesignGui - -#endif // GUI_TASKVIEW_TASKAPPERANCE_H diff --git a/src/Mod/PartDesign/Gui/TaskPocketParameters.cpp.orig b/src/Mod/PartDesign/Gui/TaskPocketParameters.cpp.orig deleted file mode 100644 index 507be8e45..000000000 --- a/src/Mod/PartDesign/Gui/TaskPocketParameters.cpp.orig +++ /dev/null @@ -1,453 +0,0 @@ -/*************************************************************************** - * Copyright (c) 2011 Juergen Riegel * - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file COPYING.LIB. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * - ***************************************************************************/ - - -#include "PreCompiled.h" - -#ifndef _PreComp_ -# include -# include -# include -# include -#endif - -#include "ui_TaskPocketParameters.h" -#include "TaskPocketParameters.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "TaskSketchBasedParameters.h" -#include "ReferenceSelection.h" -#include "Workbench.h" - -using namespace PartDesignGui; -using namespace Gui; - -/* TRANSLATOR PartDesignGui::TaskPocketParameters */ - -TaskPocketParameters::TaskPocketParameters(ViewProviderPocket *PocketView,QWidget *parent) - : TaskSketchBasedParameters(PocketView, parent, "PartDesign_Pocket",tr("Pocket parameters")) -{ - // we need a separate container widget to add all controls to - proxy = new QWidget(this); - ui = new Ui_TaskPocketParameters(); - ui->setupUi(proxy); - QMetaObject::connectSlotsByName(this); - - connect(ui->pocketLength, SIGNAL(valueChanged(double)), - this, SLOT(onLengthChanged(double))); - connect(ui->spinOffset, SIGNAL(valueChanged(double)), - this, SLOT(onOffsetChanged(double))); - connect(ui->checkBoxMidplane, SIGNAL(toggled(bool)), - this, SLOT(onMidplaneChanged(bool))); - connect(ui->checkBoxReversed, SIGNAL(toggled(bool)), - this, SLOT(onReversedChanged(bool))); - connect(ui->changeMode, SIGNAL(currentIndexChanged(int)), - this, SLOT(onModeChanged(int))); - connect(ui->buttonFace, SIGNAL(pressed()), - this, SLOT(onButtonFace())); - connect(ui->lineFaceName, SIGNAL(textEdited(QString)), - this, SLOT(onFaceName(QString))); - connect(ui->checkBoxUpdateView, SIGNAL(toggled(bool)), - this, SLOT(onUpdateView(bool))); - - this->groupLayout()->addWidget(proxy); - - // Temporarily prevent unnecessary feature recomputes - ui->pocketLength->blockSignals(true); - ui->spinOffset->blockSignals(true); - ui->checkBoxMidplane->blockSignals(true); - ui->checkBoxReversed->blockSignals(true); - ui->buttonFace->blockSignals(true); - ui->lineFaceName->blockSignals(true); - ui->changeMode->blockSignals(true); - - // Get the feature data - PartDesign::Pocket* pcPocket = static_cast(vp->getObject()); - double l = pcPocket->Length.getValue(); - double off = pcPocket->Offset.getValue(); - bool midplane = pcPocket->Midplane.getValue(); - bool reversed = pcPocket->Reversed.getValue(); - int index = pcPocket->Type.getValue(); // must extract value here, clear() kills it! - App::DocumentObject* obj = pcPocket->UpToFace.getValue(); - std::vector subStrings = pcPocket->UpToFace.getSubValues(); - std::string upToFace; - int faceId = -1; - if ((obj != NULL) && !subStrings.empty()) { - upToFace = subStrings.front(); - if (upToFace.substr(0,4) == "Face") - faceId = std::atoi(&upToFace[4]); - } - - // Fill data into dialog elements - ui->pocketLength->setMinimum(0); - ui->pocketLength->setMaximum(INT_MAX); - ui->pocketLength->setValue(l); - ui->spinOffset->setMinimum(-INT_MAX); - ui->spinOffset->setMaximum(INT_MAX); - ui->spinOffset->setValue(off); - ui->checkBoxMidplane->setChecked(midplane); - ui->checkBoxReversed->setChecked(reversed); - if ((obj != NULL) && PartDesign::Feature::isDatum(obj)) - ui->lineFaceName->setText(QString::fromAscii(obj->getNameInDocument())); - else if (faceId >= 0) - ui->lineFaceName->setText(QString::fromAscii(obj->getNameInDocument()) + QString::fromAscii(":") + tr("Face") + - QString::number(faceId)); - else - ui->lineFaceName->setText(tr("No face selected")); - ui->lineFaceName->setProperty("FaceName", QByteArray(upToFace.c_str())); - ui->changeMode->clear(); - ui->changeMode->insertItem(0, tr("Dimension")); - ui->changeMode->insertItem(1, tr("Through all")); - ui->changeMode->insertItem(2, tr("To first")); - ui->changeMode->insertItem(3, tr("Up to face")); - ui->changeMode->setCurrentIndex(index); - - // Bind input fields to properties - ui->pocketLength->bind(pcPocket->Length); - - ui->pocketLength->blockSignals(false); - ui->spinOffset->blockSignals(false); - ui->checkBoxMidplane->blockSignals(false); - ui->checkBoxReversed->blockSignals(false); - ui->buttonFace->blockSignals(false); - ui->lineFaceName->blockSignals(false); - ui->changeMode->blockSignals(false); - - ui->checkBoxReversed->setVisible(true); - - updateUI(index); - - //// check if the sketch has support - //Sketcher::SketchObject *pcSketch; - //if (pcPocket->Sketch.getValue()) { - // pcSketch = static_cast(pcPocket->Sketch.getValue()); - // if (pcSketch->Support.getValue()) - // // in case of sketch with support, reverse makes no sense (goes into the part) - // ui->checkBoxReversed->setEnabled(0); - // else - // ui->checkBoxReversed->setChecked(reversed); - //} -} - -void TaskPocketParameters::updateUI(int index) -{ - if (index == 0) { // Only this option requires a numeric value // Dimension - ui->pocketLength->setVisible(true); - ui->pocketLength->setEnabled(true); - ui->pocketLength->selectAll(); - QMetaObject::invokeMethod(ui->pocketLength, "setFocus", Qt::QueuedConnection); - ui->spinOffset->setVisible(false); - ui->spinOffset->setEnabled(false); - ui->spinOffset->setEnabled(false); - ui->checkBoxMidplane->setEnabled(true); - // Reverse only makes sense if Midplane is not true - ui->checkBoxReversed->setEnabled(!ui->checkBoxMidplane->isChecked()); // Will flip direction of dimension - ui->buttonFace->setEnabled(false); - ui->lineFaceName->setEnabled(false); - onButtonFace(false); - } else if (index == 1) { // Through all - ui->checkBoxMidplane->setEnabled(true); - ui->checkBoxReversed->setEnabled(!ui->checkBoxMidplane->isChecked()); // Will flip direction of through all - ui->pocketLength->setVisible(false); - ui->pocketLength->setEnabled(false); - ui->spinOffset->setVisible(false); - ui->spinOffset->setVisible(false); - ui->spinOffset->setEnabled(false); - ui->buttonFace->setEnabled(false); - ui->lineFaceName->setEnabled(false); - onButtonFace(false); - } else if (index == 2) { // Neither value nor face required // To First - ui->pocketLength->setEnabled(false); - ui->pocketLength->setVisible(false); - ui->checkBoxMidplane->setEnabled(false); // Can't have a midplane to a single face - ui->checkBoxReversed->setEnabled(false); // Will change the direction it seeks for its first face? - // Doesnt work so is currently disabled. Fix probably lies - // somwhere in IF block on line 125 of FeaturePocket.cpp - ui->labelLength->setVisible(false); - ui->spinOffset->setVisible(true); - ui->spinOffset->setEnabled(true); - ui->labelOffset->setVisible(true); - ui->buttonFace->setEnabled(false); - ui->lineFaceName->setEnabled(false); - onButtonFace(false); - } else if (index == 3) { // Only this option requires to select a face // Up to face - ui->pocketLength->setEnabled(false); - ui->pocketLength->setVisible(false); - ui->labelLength->setVisible(false); - ui->spinOffset->setVisible(true); - ui->spinOffset->setEnabled(true); - ui->labelOffset->setVisible(true); - ui->checkBoxMidplane->setEnabled(false); - ui->checkBoxReversed->setEnabled(false); // No need for reverse since user-chosen face will dtermine direction - ui->buttonFace->setEnabled(true); - ui->lineFaceName->setEnabled(true); - QMetaObject::invokeMethod(ui->lineFaceName, "setFocus", Qt::QueuedConnection); - // Go into reference selection mode if no face has been selected yet - if (ui->lineFaceName->text().isEmpty() || (ui->lineFaceName->text() == tr("No face selected"))) - onButtonFace(true); - } -} - -void TaskPocketParameters::onSelectionChanged(const Gui::SelectionChanges& msg) -{ - if (msg.Type == Gui::SelectionChanges::AddSelection) { - QString refText = onAddSelection(msg); - if (refText.length() > 0) { - ui->lineFaceName->blockSignals(true); - ui->lineFaceName->setText(refText); - ui->lineFaceName->setProperty("FaceName", QByteArray(msg.pSubName)); - ui->lineFaceName->blockSignals(false); - // Turn off reference selection mode - onButtonFace(false); - } else { - ui->lineFaceName->blockSignals(true); - ui->lineFaceName->setText(tr("No face selected")); - ui->lineFaceName->setProperty("FaceName", QByteArray()); - ui->lineFaceName->blockSignals(false); - } - } - else if (msg.Type == Gui::SelectionChanges::ClrSelection) { - ui->lineFaceName->blockSignals(true); - ui->lineFaceName->setText(tr("No face selected")); - ui->lineFaceName->setProperty("FaceName", QByteArray()); - ui->lineFaceName->blockSignals(false); - } -} - -void TaskPocketParameters::onLengthChanged(double len) -{ - PartDesign::Pocket* pcPocket = static_cast(vp->getObject()); - pcPocket->Length.setValue(len); - recomputeFeature(); -} - -void TaskPocketParameters::onOffsetChanged(double len) -{ - PartDesign::Pocket* pcPocket = static_cast(vp->getObject()); - pcPocket->Offset.setValue(len); - recomputeFeature(); -} - -void TaskPocketParameters::onMidplaneChanged(bool on) -{ - PartDesign::Pocket* pcPocket = static_cast(vp->getObject()); - pcPocket->Midplane.setValue(on); - ui->checkBoxReversed->setEnabled(!on); - recomputeFeature(); -} - -void TaskPocketParameters::onReversedChanged(bool on) -{ - PartDesign::Pocket* pcPocket = static_cast(vp->getObject()); - pcPocket->Reversed.setValue(on); - recomputeFeature(); -} - -void TaskPocketParameters::onModeChanged(int index) -{ - PartDesign::Pocket* pcPocket = static_cast(vp->getObject()); - - switch (index) { - case 0: - // Why? See below for "UpToFace" - pcPocket->Type.setValue("Length"); - if (oldLength < Precision::Confusion()) - oldLength = 5.0; - pcPocket->Length.setValue(oldLength); - ui->pocketLength->setValue(oldLength); - break; - case 1: - oldLength = pcPocket->Length.getValue(); - pcPocket->Type.setValue("ThroughAll"); - break; - case 2: - oldLength = pcPocket->Length.getValue(); - pcPocket->Type.setValue("UpToFirst"); - break; - case 3: - // Because of the code at the begining of Pocket::execute() which is used to detect - // broken legacy parts, we must set the length to zero here! - oldLength = pcPocket->Length.getValue(); - pcPocket->Type.setValue("UpToFace"); - pcPocket->Length.setValue(0.0); - ui->pocketLength->setValue(0.0); - break; - default: - pcPocket->Type.setValue("Length"); - } - - updateUI(index); - recomputeFeature(); -} - -void TaskPocketParameters::onButtonFace(const bool pressed) { - TaskSketchBasedParameters::onSelectReference(pressed, false, true, false); - - // Update button if onButtonFace() is called explicitly - ui->buttonFace->setChecked(pressed); -} - -void TaskPocketParameters::onFaceName(const QString& text) -{ - ui->lineFaceName->setProperty("FaceName", TaskSketchBasedParameters::onFaceName(text)); -} - -double TaskPocketParameters::getLength(void) const -{ - return ui->pocketLength->value().getValue(); -} - -double TaskPocketParameters::getOffset(void) const -{ - return ui->spinOffset->value(); -} - -bool TaskPocketParameters::getReversed(void) const -{ - return ui->checkBoxReversed->isChecked(); -} - -int TaskPocketParameters::getMode(void) const -{ - return ui->changeMode->currentIndex(); -} - -QString TaskPocketParameters::getFaceName(void) const -{ - // TODO Make it return None rather than empty string (2015-11-03, Fat-Zer) - if (getMode() == 3) { - QString faceName = ui->lineFaceName->property("FaceName").toString(); - if (!faceName.isEmpty()) { - return getFaceReference(ui->lineFaceName->text(), faceName); - } - } - return QString (); -} - -TaskPocketParameters::~TaskPocketParameters() -{ - delete ui; -} - -void TaskPocketParameters::changeEvent(QEvent *e) -{ - TaskBox::changeEvent(e); - if (e->type() == QEvent::LanguageChange) { - ui->pocketLength->blockSignals(true); - ui->spinOffset->blockSignals(true); - ui->lineFaceName->blockSignals(true); - ui->changeMode->blockSignals(true); - int index = ui->changeMode->currentIndex(); - ui->retranslateUi(proxy); - ui->changeMode->clear(); - ui->changeMode->addItem(tr("Dimension")); - ui->changeMode->addItem(tr("Through all")); - ui->changeMode->addItem(tr("To first")); - ui->changeMode->addItem(tr("Up to face")); - ui->changeMode->setCurrentIndex(index); - - QStringList parts = ui->lineFaceName->text().split(QChar::fromAscii(':')); - QByteArray upToFace = ui->lineFaceName->property("FaceName").toByteArray(); - int faceId = -1; - bool ok = false; - if (upToFace.indexOf("Face") == 0) { - faceId = upToFace.remove(0,4).toInt(&ok); - } - ui->lineFaceName->setText(ok ? - parts[0] + QString::fromAscii(":") + tr("Face") + QString::number(faceId) : - tr("No face selected")); - ui->pocketLength->blockSignals(false); - ui->spinOffset->blockSignals(false); - ui->lineFaceName->blockSignals(false); - ui->changeMode->blockSignals(false); - } -} - -void TaskPocketParameters::apply() -{ - std::string name = vp->getObject()->getNameInDocument(); - - //Gui::Command::openCommand("Pocket changed"); - ui->pocketLength->apply(); - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Type = %u",name.c_str(),getMode()); - QString facename = getFaceName(); - - if (!facename.isEmpty()) { - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.UpToFace = %s", - name.c_str(), facename.toLatin1().data() ); - } else - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.UpToFace = None", name.c_str()); - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Reversed = %i", name.c_str(), getReversed()?1:0); - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Offset = %f", name.c_str(), getOffset()); -} - -//************************************************************************** -//************************************************************************** -// TaskDialog -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -TaskDlgPocketParameters::TaskDlgPocketParameters(ViewProviderPocket *PocketView) - : TaskDlgSketchBasedParameters(PocketView) -{ - assert(vp); - parameter = new TaskPocketParameters(static_cast(vp)); - - Content.push_back(parameter); -} - -TaskDlgPocketParameters::~TaskDlgPocketParameters() -{ - -} - -//==== calls from the TaskView =============================================================== - -bool TaskDlgPocketParameters::accept() -{ -<<<<<<< b551f892abed242e90afa77240bbdd7dcf7fc45c - try { - parameter->apply(); - } - catch (const Base::Exception& e) { - QMessageBox::warning(parameter, tr("Input error"), QString::fromLatin1(e.what())); - return false; - } -======= - parameter->apply(); ->>>>>>> PartDesignGui: Make DressUp and SketchSupport propertie dialogs use common accept() structure - - return TaskDlgSketchBasedParameters::accept(); -} - - -#include "moc_TaskPocketParameters.cpp" diff --git a/src/Mod/PartDesign/Gui/TaskPocketParameters.h.orig b/src/Mod/PartDesign/Gui/TaskPocketParameters.h.orig deleted file mode 100644 index 6678b58f8..000000000 --- a/src/Mod/PartDesign/Gui/TaskPocketParameters.h.orig +++ /dev/null @@ -1,119 +0,0 @@ -/*************************************************************************** - * Copyright (c) 2011 Juergen Riegel * - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file COPYING.LIB. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * - ***************************************************************************/ - - -#ifndef GUI_TASKVIEW_TaskPocketParameters_H -#define GUI_TASKVIEW_TaskPocketParameters_H - -#include -#include -#include - -#include "TaskSketchBasedParameters.h" -#include "ViewProviderPocket.h" - -class Ui_TaskPocketParameters; - -namespace App { -class Property; -} - -namespace Gui { -class ViewProvider; -} - -namespace PartDesignGui { - - - -class TaskPocketParameters : public TaskSketchBasedParameters -{ - Q_OBJECT - -public: - TaskPocketParameters(ViewProviderPocket *PocketView,QWidget *parent = 0); - ~TaskPocketParameters(); - - bool getReversed(void) const; - QByteArray getFaceName(void) const; - const bool updateView() const; - void apply(); - -private Q_SLOTS: - void onLengthChanged(double); - void onMidplaneChanged(bool); - void onReversedChanged(bool); - void onModeChanged(int); - void onButtonFace(const bool pressed = true); - void onFaceName(const QString& text); - -protected: - void changeEvent(QEvent *e); - -private: - double getLength(void) const; - bool getMidplane(void) const; - int getMode(void) const; - void onSelectionChanged(const Gui::SelectionChanges& msg); - void updateUI(int index); - -private: - QWidget* proxy; - Ui_TaskPocketParameters* ui; - double oldLength; -}; - -/// simulation dialog for the TaskView -class TaskDlgPocketParameters : public TaskDlgSketchBasedParameters -{ - Q_OBJECT - -public: - TaskDlgPocketParameters(ViewProviderPocket *PocketView); - ~TaskDlgPocketParameters(); - - ViewProviderPocket* getPocketView() const - { return static_cast(vp); } - - -public: - /// is called by the framework if the dialog is accepted (Ok) - virtual bool accept(); -<<<<<<< 0973b40e8e489ddbf6455e9a2e80b0520f143b58 - /// is called by the framework if the dialog is rejected (Cancel) - virtual bool reject(); - virtual bool isAllowedAlterDocument(void) const - { return false; } - - /// returns for Close and Help button - virtual QDialogButtonBox::StandardButtons getStandardButtons(void) const - { return QDialogButtonBox::Ok|QDialogButtonBox::Cancel; } -======= ->>>>>>> Refactored code of SketchBased features to have common code in an abstract superclass - -protected: - TaskPocketParameters *parameter; -}; - -} //namespace PartDesignGui - -#endif // GUI_TASKVIEW_TASKAPPERANCE_H diff --git a/src/Mod/PartDesign/Gui/TaskPolarPatternParameters.cpp.orig b/src/Mod/PartDesign/Gui/TaskPolarPatternParameters.cpp.orig deleted file mode 100644 index 6bc94d59e..000000000 --- a/src/Mod/PartDesign/Gui/TaskPolarPatternParameters.cpp.orig +++ /dev/null @@ -1,435 +0,0 @@ -/****************************************************************************** - * Copyright (c)2012 Jan Rheinlaender * - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file COPYING.LIB. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * - ******************************************************************************/ - - -#include "PreCompiled.h" - -#ifndef _PreComp_ -# include -# include -#endif - -#include "ui_TaskPolarPatternParameters.h" -#include "TaskPolarPatternParameters.h" -#include "TaskMultiTransformParameters.h" -#include "Workbench.h" -#include "ReferenceSelection.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace PartDesignGui; -using namespace Gui; - -/* TRANSLATOR PartDesignGui::TaskPolarPatternParameters */ - -TaskPolarPatternParameters::TaskPolarPatternParameters(ViewProviderTransformed *TransformedView,QWidget *parent) - : TaskTransformedParameters(TransformedView, parent) -{ - // we need a separate container widget to add all controls to - proxy = new QWidget(this); - ui = new Ui_TaskPolarPatternParameters(); - ui->setupUi(proxy); - QMetaObject::connectSlotsByName(this); - - this->groupLayout()->addWidget(proxy); - - ui->buttonOK->hide(); - ui->checkBoxUpdateView->setEnabled(true); - - selectionMode = none; - - blockUpdate = false; // Hack, sometimes it is NOT false although set to false in Transformed::Transformed()!! - setupUI(); -} - -TaskPolarPatternParameters::TaskPolarPatternParameters(TaskMultiTransformParameters *parentTask, QLayout *layout) - : TaskTransformedParameters(parentTask) -{ - proxy = new QWidget(parentTask); - ui = new Ui_TaskPolarPatternParameters(); - ui->setupUi(proxy); - connect(ui->buttonOK, SIGNAL(pressed()), - parentTask, SLOT(onSubTaskButtonOK())); - QMetaObject::connectSlotsByName(this); - - layout->addWidget(proxy); - - ui->buttonOK->setEnabled(true); - ui->buttonAddFeature->hide(); - ui->buttonRemoveFeature->hide(); - ui->listWidgetFeatures->hide(); - ui->checkBoxUpdateView->hide(); - - selectionMode = none; - - blockUpdate = false; // Hack, sometimes it is NOT false although set to false in Transformed::Transformed()!! - setupUI(); -} - -void TaskPolarPatternParameters::setupUI() -{ - connect(ui->buttonAddFeature, SIGNAL(toggled(bool)), this, SLOT(onButtonAddFeature(bool))); - connect(ui->buttonRemoveFeature, SIGNAL(toggled(bool)), this, SLOT(onButtonRemoveFeature(bool))); - // Create context menu - QAction* action = new QAction(tr("Remove"), this); - ui->listWidgetFeatures->addAction(action); - connect(action, SIGNAL(triggered()), this, SLOT(onFeatureDeleted())); - ui->listWidgetFeatures->setContextMenuPolicy(Qt::ActionsContextMenu); - - updateViewTimer = new QTimer(this); - updateViewTimer->setSingleShot(true); - updateViewTimer->setInterval(getUpdateViewTimeout()); - - connect(updateViewTimer, SIGNAL(timeout()), - this, SLOT(onUpdateViewTimer())); - connect(ui->comboAxis, SIGNAL(activated(int)), - this, SLOT(onAxisChanged(int))); - connect(ui->checkReverse, SIGNAL(toggled(bool)), - this, SLOT(onCheckReverse(bool))); - connect(ui->polarAngle, SIGNAL(valueChanged(double)), - this, SLOT(onAngle(double))); - connect(ui->spinOccurrences, SIGNAL(valueChanged(uint)), - this, SLOT(onOccurrences(uint))); - connect(ui->checkBoxUpdateView, SIGNAL(toggled(bool)), - this, SLOT(onUpdateView(bool))); - - // Get the feature data - PartDesign::PolarPattern* pcPolarPattern = static_cast(getObject()); - std::vector originals = pcPolarPattern->Originals.getValues(); - - // Fill data into dialog elements - for (std::vector::const_iterator i = originals.begin(); i != originals.end(); ++i) - { - if ((*i) != NULL) - ui->listWidgetFeatures->addItem(QString::fromLatin1((*i)->getNameInDocument())); - } - // --------------------- - - ui->polarAngle->bind(pcPolarPattern->Angle); - ui->spinOccurrences->setMaximum(INT_MAX); - ui->spinOccurrences->bind(pcPolarPattern->Occurrences); - - ui->comboAxis->setEnabled(true); - ui->checkReverse->setEnabled(true); - ui->polarAngle->setEnabled(true); - ui->spinOccurrences->setEnabled(true); - - App::DocumentObject* sketch = getSketchObject(); - if (!(sketch->isDerivedFrom(Part::Part2DObject::getClassTypeId()))) - sketch = 0; - this->axesLinks.setCombo(*(ui->comboAxis)); - this->fillAxisCombo(axesLinks, static_cast(sketch)); - updateUI(); - - //show the parts coordinate system axis for selection - App::Part* part = getPartFor(getObject(), false); - if(part) { - auto app_origin = part->getObjectsOfType(App::Origin::getClassTypeId()); - if(!app_origin.empty()) { - ViewProviderOrigin* origin; - origin = static_cast(Gui::Application::Instance->activeDocument()->getViewProvider(app_origin[0])); - origin->setTemporaryVisibilityMode(true, Gui::Application::Instance->activeDocument()); - origin->setTemporaryVisibilityAxis(true); - } - } -} - -void TaskPolarPatternParameters::updateUI() -{ - if (blockUpdate) - return; - blockUpdate = true; - - PartDesign::PolarPattern* pcPolarPattern = static_cast(getObject()); - - bool reverse = pcPolarPattern->Reversed.getValue(); - double angle = pcPolarPattern->Angle.getValue(); - unsigned occurrences = pcPolarPattern->Occurrences.getValue(); - - if (axesLinks.setCurrentLink(pcPolarPattern->Axis) == -1){ - //failed to set current, because the link isnt in the list yet - axesLinks.addLink(pcPolarPattern->Axis, getRefStr(pcPolarPattern->Axis.getValue(),pcPolarPattern->Axis.getSubValues())); - axesLinks.setCurrentLink(pcPolarPattern->Axis); - } - - // Note: These three lines would trigger onLength(), on Occurrences() and another updateUI() if we - // didn't check for blockUpdate - ui->checkReverse->setChecked(reverse); - ui->polarAngle->setValue(angle); - ui->spinOccurrences->setValue(occurrences); - - blockUpdate = false; -} - -void TaskPolarPatternParameters::onUpdateViewTimer() -{ - recomputeFeature(); -} - -void TaskPolarPatternParameters::kickUpdateViewTimer() const -{ - updateViewTimer->start(); -} - -void TaskPolarPatternParameters::onSelectionChanged(const Gui::SelectionChanges& msg) -{ - if (msg.Type == Gui::SelectionChanges::AddSelection) { - - if (originalSelected(msg)) { - if (selectionMode == addFeature) - ui->listWidgetFeatures->addItem(QString::fromLatin1(msg.pObjectName)); - else - removeItemFromListWidget(ui->listWidgetFeatures, msg.pObjectName); - exitSelectionMode(); - } else if (selectionMode == reference) { - // Note: ReferenceSelection has already checked the selection for validity - exitSelectionMode(); - std::vector axes; - App::DocumentObject* selObj; - PartDesign::PolarPattern* pcPolarPattern = static_cast(getObject()); - getReferencedSelection(pcPolarPattern, msg, selObj, axes); - pcPolarPattern->Axis.setValue(selObj, axes); - - recomputeFeature(); - updateUI(); - } else if( strstr(msg.pObjectName, App::Part::BaselineTypes[0]) == nullptr || - strstr(msg.pObjectName, App::Part::BaselineTypes[1]) == nullptr || - strstr(msg.pObjectName, App::Part::BaselineTypes[2]) == nullptr) { - - std::vector axes; - App::DocumentObject* selObj; - PartDesign::PolarPattern* pcPolarPattern = static_cast(getObject()); - getReferencedSelection(pcPolarPattern, msg, selObj, axes); - pcPolarPattern->Axis.setValue(selObj, axes); - - recomputeFeature(); - updateUI(); - } - } -} - -void TaskPolarPatternParameters::clearButtons() -{ - ui->buttonAddFeature->setChecked(false); - ui->buttonRemoveFeature->setChecked(false); -} - -void TaskPolarPatternParameters::onCheckReverse(const bool on) { - if (blockUpdate) - return; - PartDesign::PolarPattern* pcPolarPattern = static_cast(getObject()); - pcPolarPattern->Reversed.setValue(on); - - exitSelectionMode(); - kickUpdateViewTimer(); -} - -void TaskPolarPatternParameters::onAngle(const double a) { - if (blockUpdate) - return; - PartDesign::PolarPattern* pcPolarPattern = static_cast(getObject()); - pcPolarPattern->Angle.setValue(a); - - exitSelectionMode(); - kickUpdateViewTimer(); -} - -void TaskPolarPatternParameters::onOccurrences(const uint n) { - if (blockUpdate) - return; - PartDesign::PolarPattern* pcPolarPattern = static_cast(getObject()); - pcPolarPattern->Occurrences.setValue(n); - - exitSelectionMode(); - kickUpdateViewTimer(); -} - -void TaskPolarPatternParameters::onAxisChanged(int num) { - if (blockUpdate) - return; - PartDesign::PolarPattern* pcPolarPattern = static_cast(getObject()); - - try{ - if(axesLinks.getCurrentLink().getValue() == 0){ - // enter reference selection mode - hideObject(); - showBase(); - selectionMode = reference; - Gui::Selection().clearSelection(); - addReferenceSelectionGate(true, false); - } else { - exitSelectionMode(); - pcPolarPattern->Axis.Paste(axesLinks.getCurrentLink()); - } - } catch (Base::Exception &e) { - QMessageBox::warning(0,tr("Error"),QString::fromAscii(e.what())); - } - - kickUpdateViewTimer(); -} - -void TaskPolarPatternParameters::onUpdateView(bool on) -{ - blockUpdate = !on; - if (on) { - // Do the same like in TaskDlgPolarPatternParameters::accept() but without doCommand - PartDesign::PolarPattern* pcPolarPattern = static_cast(getObject()); - std::vector axes; - App::DocumentObject* obj; - - getAxis(obj, axes); - pcPolarPattern->Axis.setValue(obj,axes); - pcPolarPattern->Reversed.setValue(getReverse()); - pcPolarPattern->Angle.setValue(getAngle()); - pcPolarPattern->Occurrences.setValue(getOccurrences()); - - recomputeFeature(); - } -} - -void TaskPolarPatternParameters::onFeatureDeleted(void) -{ - PartDesign::Transformed* pcTransformed = getObject(); - std::vector originals = pcTransformed->Originals.getValues(); - originals.erase(originals.begin() + ui->listWidgetFeatures->currentRow()); - pcTransformed->Originals.setValues(originals); - ui->listWidgetFeatures->model()->removeRow(ui->listWidgetFeatures->currentRow()); - recomputeFeature(); -} - -void TaskPolarPatternParameters::getAxis(App::DocumentObject*& obj, std::vector& sub) const -{ - const App::PropertyLinkSub &lnk = axesLinks.getCurrentLink(); - obj = lnk.getValue(); - sub = lnk.getSubValues(); -} - -const bool TaskPolarPatternParameters::getReverse(void) const -{ - return ui->checkReverse->isChecked(); -} - -const double TaskPolarPatternParameters::getAngle(void) const -{ - return ui->polarAngle->value().getValue(); -} - -const unsigned TaskPolarPatternParameters::getOccurrences(void) const -{ - return ui->spinOccurrences->value(); -} - - -TaskPolarPatternParameters::~TaskPolarPatternParameters() -{ - //hide the parts coordinate system axis for selection - App::Part* part = getPartFor(getObject(), false); - if(part) { - auto app_origin = part->getObjectsOfType(App::Origin::getClassTypeId()); - if(!app_origin.empty()) { - ViewProviderOrigin* origin; - origin = static_cast(Gui::Application::Instance->activeDocument()->getViewProvider(app_origin[0])); - origin->setTemporaryVisibilityMode(false); - } - } - - delete ui; - if (proxy) - delete proxy; -} - -void TaskPolarPatternParameters::changeEvent(QEvent *e) -{ - TaskBox::changeEvent(e); - if (e->type() == QEvent::LanguageChange) { - ui->retranslateUi(proxy); - } -} - -void TaskPolarPatternParameters::apply() -{ - std::string name = TransformedView->getObject()->getNameInDocument(); - std::vector axes; - App::DocumentObject* obj; - getAxis(obj, axes); - std::string axis = getPythonStr(obj, axes); - if (!axis.empty() && obj) { - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Axis = %s", name.c_str(), axis.c_str()); - } else { - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Axis = None", name.c_str()); - } - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Reversed = %u",name.c_str(),getReverse()); - ui->polarAngle->apply(); - ui->spinOccurrences->apply(); - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.recompute()"); - if (!TransformedView->getObject()->isValid()) - throw Base::Exception(TransformedView->getObject()->getStatusString()); - Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().resetEdit()"); - Gui::Command::commitCommand(); -} - -//************************************************************************** -//************************************************************************** -// TaskDialog -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -TaskDlgPolarPatternParameters::TaskDlgPolarPatternParameters(ViewProviderPolarPattern *PolarPatternView) - : TaskDlgTransformedParameters(PolarPatternView) -{ - parameter = new TaskPolarPatternParameters(PolarPatternView); - - Content.push_back(parameter); -} -//==== calls from the TaskView =============================================================== - -bool TaskDlgPolarPatternParameters::accept() -{ - - parameter->apply(); -<<<<<<< a6aea83ec9ef83d52a06178b32175b3e79f73c65 - } - catch (const Base::Exception& e) { - QMessageBox::warning(parameter, tr("Input error"), QString::fromLatin1(e.what())); - return false; - } -======= ->>>>>>> PartDesign: make transform parameter dialogs use common base code with other dialogs - - return TaskDlgTransformedParameters::accept(); -} - -#include "moc_TaskPolarPatternParameters.cpp" diff --git a/src/Mod/PartDesign/Gui/TaskRevolutionParameters.cpp.orig b/src/Mod/PartDesign/Gui/TaskRevolutionParameters.cpp.orig deleted file mode 100644 index 3d058d31d..000000000 --- a/src/Mod/PartDesign/Gui/TaskRevolutionParameters.cpp.orig +++ /dev/null @@ -1,410 +0,0 @@ -/*************************************************************************** - * Copyright (c) 2011 Juergen Riegel * - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file COPYING.LIB. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * - ***************************************************************************/ - - -#include "PreCompiled.h" - -#ifndef _PreComp_ -#endif - -#include "ui_TaskRevolutionParameters.h" -#include "TaskRevolutionParameters.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "ReferenceSelection.h" -#include "TaskSketchBasedParameters.h" -#include "Workbench.h" - - -using namespace PartDesignGui; -using namespace Gui; - -/* TRANSLATOR PartDesignGui::TaskRevolutionParameters */ - -TaskRevolutionParameters::TaskRevolutionParameters(ViewProviderRevolution *RevolutionView,QWidget *parent) - : TaskSketchBasedParameters(RevolutionView, parent, "PartDesign_Revolution",tr("Revolution parameters")) -{ - // we need a separate container widget to add all controls to - proxy = new QWidget(this); - ui = new Ui_TaskRevolutionParameters(); - ui->setupUi(proxy); - QMetaObject::connectSlotsByName(this); - - connect(ui->revolveAngle, SIGNAL(valueChanged(double)), - this, SLOT(onAngleChanged(double))); - connect(ui->axis, SIGNAL(activated(int)), - this, SLOT(onAxisChanged(int))); - connect(ui->checkBoxMidplane, SIGNAL(toggled(bool)), - this, SLOT(onMidplane(bool))); - connect(ui->checkBoxReversed, SIGNAL(toggled(bool)), - this, SLOT(onReversed(bool))); - connect(ui->checkBoxUpdateView, SIGNAL(toggled(bool)), - this, SLOT(onUpdateView(bool))); - - this->groupLayout()->addWidget(proxy); - - // Temporarily prevent unnecessary feature recomputes - ui->revolveAngle->blockSignals(true); - ui->axis->blockSignals(true); - ui->checkBoxMidplane->blockSignals(true); - ui->checkBoxReversed->blockSignals(true); - - PartDesign::Revolution* pcRevolution = static_cast(vp->getObject()); - double l = pcRevolution->Angle.getValue(); - bool mirrored = pcRevolution->Midplane.getValue(); - bool reversed = pcRevolution->Reversed.getValue(); - - ui->revolveAngle->setValue(l); -<<<<<<< f0798a82fe8f03db57aca4f634d2123486daaea0 - - int count=pcRevolution->getSketchAxisCount(); - - for (int i=ui->axis->count()-1; i >= count+2; i--) - ui->axis->removeItem(i); - for (int i=ui->axis->count(); i < count+2; i++) - ui->axis->addItem(QString::fromLatin1("Sketch axis %1").arg(i-2)); - - int pos=-1; - - App::DocumentObject *pcReferenceAxis = pcRevolution->ReferenceAxis.getValue(); - const std::vector &subReferenceAxis = pcRevolution->ReferenceAxis.getSubValues(); - if (pcReferenceAxis && pcReferenceAxis == pcRevolution->Sketch.getValue()) { - assert(subReferenceAxis.size()==1); - if (subReferenceAxis[0] == "V_Axis") - pos = 0; - else if (subReferenceAxis[0] == "H_Axis") - pos = 1; - else if (subReferenceAxis[0].size() > 4 && subReferenceAxis[0].substr(0,4) == "Axis") - pos = 2 + std::atoi(subReferenceAxis[0].substr(4,4000).c_str()); - } - - if (pos < 0 || pos >= ui->axis->count()) { - ui->axis->addItem(tr("Undefined")); - pos = ui->axis->count()-1; - } - - ui->axis->setCurrentIndex(pos); -======= - blockUpdate = false; - updateUI(); ->>>>>>> Enable edges and datum lines as rotation axis for Groove and Revolution features - - ui->checkBoxMidplane->setChecked(mirrored); - ui->checkBoxReversed->setChecked(reversed); - ui->revolveAngle->bind(pcRevolution->Angle); - - ui->doubleSpinBox->blockSignals(false); - ui->axis->blockSignals(false); - ui->checkBoxMidplane->blockSignals(false); - ui->checkBoxReversed->blockSignals(false); - - setFocus (); -} - -void TaskRevolutionParameters::updateUI() -{ - if (blockUpdate) - return; - blockUpdate = true; - - PartDesign::Revolution* pcRevolution = static_cast(vp->getObject()); - - App::DocumentObject* pcReferenceAxis = pcRevolution->ReferenceAxis.getValue(); - std::vector sub = pcRevolution->ReferenceAxis.getSubValues(); - - // Add user-defined sketch axes to the reference selection combo box - Sketcher::SketchObject *pcSketch = static_cast(pcRevolution->Sketch.getValue()); - int maxcount=2; - if (pcSketch) - maxcount += pcSketch->getAxisCount(); - - for (int i=ui->axis->count()-1; i >= 2; i--) - ui->axis->removeItem(i); - for (int i=ui->axis->count(); i < maxcount; i++) - ui->axis->addItem(QString::fromAscii("Sketch axis %1").arg(i-5)); - - bool undefined = false; - if (pcReferenceAxis != NULL && !sub.empty()) { - if (sub.front() == "H_Axis") - ui->axis->setCurrentIndex(0); - else if (sub.front() == "V_Axis") - ui->axis->setCurrentIndex(1); - else if (sub.front().size() > 4 && sub.front().substr(0,4) == "Axis") { - int pos = 2 + std::atoi(sub.front().substr(4,4000).c_str()); - if (pos <= maxcount) - ui->axis->setCurrentIndex(pos); - else - undefined = true; - } else { - ui->axis->addItem(getRefStr(pcReferenceAxis, sub)); - ui->axis->setCurrentIndex(maxcount); - } - } else { - undefined = true; - } - - ui->axis->addItem(tr("Select reference...")); - - blockUpdate = false; -} - -void TaskRevolutionParameters::onSelectionChanged(const Gui::SelectionChanges& msg) -{ - if (msg.Type == Gui::SelectionChanges::AddSelection) { - PartDesign::Revolution* pcRevolution = static_cast(vp->getObject()); - - exitSelectionMode(); - if (!blockUpdate) { - std::vector axis; - App::DocumentObject* selObj; - getReferencedSelection(pcRevolution, msg, selObj, axis); - pcRevolution->ReferenceAxis.setValue(selObj, axis); - - - recomputeFeature(); - updateUI(); - } - else { - Sketcher::SketchObject *pcSketch = static_cast(pcRevolution->Sketch.getValue()); - int maxcount=2; - if (pcSketch) - maxcount += pcSketch->getAxisCount(); - for (int i=ui->axis->count()-1; i >= maxcount; i--) - ui->axis->removeItem(i); - - std::vector sub; - App::DocumentObject* selObj; - getReferencedSelection(pcRevolution, msg, selObj, sub); - ui->axis->addItem(getRefStr(selObj, sub)); - ui->axis->setCurrentIndex(maxcount); - ui->axis->addItem(tr("Select reference...")); - } - } -} - - -void TaskRevolutionParameters::onAngleChanged(double len) -{ - PartDesign::Revolution* pcRevolution = static_cast(vp->getObject()); - pcRevolution->Angle.setValue(len); - exitSelectionMode(); - recomputeFeature(); -} - -void TaskRevolutionParameters::onAxisChanged(int num) -{ - if (blockUpdate) - return; - PartDesign::Revolution* pcRevolution = static_cast(vp->getObject()); - Sketcher::SketchObject *pcSketch = static_cast(pcRevolution->Sketch.getValue()); - if (pcSketch) { - App::DocumentObject *oldRefAxis = pcRevolution->ReferenceAxis.getValue(); - std::vector oldSubRefAxis = pcRevolution->ReferenceAxis.getSubValues(); - - int maxcount = pcSketch->getAxisCount()+2; - if (num == 0) { - pcRevolution->ReferenceAxis.setValue(pcSketch, std::vector(1,"H_Axis")); - exitSelectionMode(); - } else if (num == 1) { - pcRevolution->ReferenceAxis.setValue(pcSketch, std::vector(1,"V_Axis")); - exitSelectionMode(); - } else if (num >= 2 && num < maxcount) { - QString buf = QString::fromUtf8("Axis%1").arg(num-2); - std::string str = buf.toStdString(); - pcRevolution->ReferenceAxis.setValue(pcSketch, std::vector(1,str)); - exitSelectionMode(); - } else if (num == ui->axis->count() - 1) { - // enter reference selection mode - TaskSketchBasedParameters::onSelectReference(true, true, false, true); - } else if (num == maxcount) - exitSelectionMode(); - - App::DocumentObject *newRefAxis = pcRevolution->ReferenceAxis.getValue(); - const std::vector &newSubRefAxis = pcRevolution->ReferenceAxis.getSubValues(); - if (oldRefAxis != newRefAxis || - oldSubRefAxis.size() != newSubRefAxis.size() || - oldSubRefAxis[0] != newSubRefAxis[0]) { - bool reversed = pcRevolution->suggestReversed(); - if (reversed != pcRevolution->Reversed.getValue()) { - pcRevolution->Reversed.setValue(reversed); - ui->checkBoxReversed->blockSignals(true); - ui->checkBoxReversed->setChecked(reversed); - ui->checkBoxReversed->blockSignals(false); - } - } - } - - updateUI(); - recomputeFeature(); -} - -void TaskRevolutionParameters::onMidplane(bool on) -{ - PartDesign::Revolution* pcRevolution = static_cast(vp->getObject()); - pcRevolution->Midplane.setValue(on); - recomputeFeature(); -} - -void TaskRevolutionParameters::onReversed(bool on) -{ - PartDesign::Revolution* pcRevolution = static_cast(vp->getObject()); - pcRevolution->Reversed.setValue(on); - recomputeFeature(); -} - -double TaskRevolutionParameters::getAngle(void) const -{ - return ui->revolveAngle->value().getValue(); -} - -void TaskRevolutionParameters::getReferenceAxis(App::DocumentObject*& obj, std::vector& sub) const -{ - // get the support and Sketch - PartDesign::Revolution* pcRevolution = static_cast(vp->getObject()); - obj = static_cast(pcRevolution->Sketch.getValue()); - sub = std::vector(1,""); - int maxcount=2; - if (obj) - maxcount += static_cast(obj)->getAxisCount(); - - if (obj) { - int num = ui->axis->currentIndex(); - if (num == 0) - sub[0] = "H_Axis"; - else if (num == 1) - sub[0] = "V_Axis"; - else if (num >= 2 && num < maxcount) { - QString buf = QString::fromUtf8("Axis%1").arg(num-2); - sub[0] = buf.toStdString(); - } else if (num == maxcount && ui->axis->count() == maxcount + 2) { - QStringList parts = ui->axis->currentText().split(QChar::fromAscii(':')); - obj = vp->getObject()->getDocument()->getObject(parts[0].toStdString().c_str()); - if (parts.size() > 1) - sub[0] = parts[1].toStdString(); - } else { - obj = NULL; - } - } - else - obj = NULL; -} - -bool TaskRevolutionParameters::getMidplane(void) const -{ - return ui->checkBoxMidplane->isChecked(); -} - -bool TaskRevolutionParameters::getReversed(void) const -{ - return ui->checkBoxReversed->isChecked(); -} - -TaskRevolutionParameters::~TaskRevolutionParameters() -{ - delete ui; -} - -void TaskRevolutionParameters::changeEvent(QEvent *e) -{ - TaskBox::changeEvent(e); - if (e->type() == QEvent::LanguageChange) { - ui->retranslateUi(proxy); - } -} - -void TaskRevolutionParameters::apply() -{ - App::DocumentObject* revolve = vp->getObject(); - std::string name = revolve->getNameInDocument(); - - // retrieve sketch and its support object - App::DocumentObject* sketch = 0; - App::DocumentObject* support = 0; - if (revolve->getTypeId().isDerivedFrom(PartDesign::Revolution::getClassTypeId())) { - sketch = static_cast(revolve)->Sketch.getValue(); - if (sketch) { - support = static_cast(sketch)->Support.getValue(); - } - } - - //Gui::Command::openCommand("Revolution changed"); - ui->revolveAngle->apply(); - std::vector sub; - App::DocumentObject* obj; - parameter->getReferenceAxis(obj, sub); - std::string axis = getPythonStr(obj, sub); - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.ReferenceAxis = %s",name.c_str(),axis.c_str()); - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Midplane = %i",name.c_str(), getMidplane() ? 1 : 0); - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Reversed = %i",name.c_str(), getReversed() ? 1 : 0); - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.recompute()"); - if (revolve->isValid()) { - if (sketch) - Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().hide(\"%s\")",sketch->getNameInDocument()); - if (support) - Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().hide(\"%s\")",support->getNameInDocument()); - } - Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().resetEdit()"); - Gui::Command::commitCommand(); -} - -//************************************************************************** -//************************************************************************** -// TaskDialog -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -TaskDlgRevolutionParameters::TaskDlgRevolutionParameters(ViewProviderRevolution *RevolutionView) - : TaskDlgSketchBasedParameters(RevolutionView) -{ - assert(RevolutionView); - parameter = new TaskRevolutionParameters(RevolutionView); - - Content.push_back(parameter); -} - -TaskDlgRevolutionParameters::~TaskDlgRevolutionParameters() -{ - -} - -//==== calls from the TaskView =============================================================== - -bool TaskDlgRevolutionParameters::accept() -{ - parameter->apply(); - return true; -} - - -#include "moc_TaskRevolutionParameters.cpp" diff --git a/src/Mod/PartDesign/Gui/TaskRevolutionParameters.h.orig b/src/Mod/PartDesign/Gui/TaskRevolutionParameters.h.orig deleted file mode 100644 index 1d219598d..000000000 --- a/src/Mod/PartDesign/Gui/TaskRevolutionParameters.h.orig +++ /dev/null @@ -1,111 +0,0 @@ -/*************************************************************************** - * Copyright (c) 2011 Juergen Riegel * - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file COPYING.LIB. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * - ***************************************************************************/ - - -#ifndef GUI_TASKVIEW_TaskRevolutionParameters_H -#define GUI_TASKVIEW_TaskRevolutionParameters_H - -#include -#include -#include - -#include "TaskSketchBasedParameters.h" -#include "ViewProviderRevolution.h" - -class Ui_TaskRevolutionParameters; - -namespace App { -class Property; -} - -namespace Gui { -class ViewProvider; -} - -namespace PartDesignGui { - - - -class TaskRevolutionParameters : public TaskSketchBasedParameters -{ - Q_OBJECT - -public: - TaskRevolutionParameters(ViewProviderRevolution *RevolutionView,QWidget *parent = 0); - ~TaskRevolutionParameters(); - - void apply(); - -private Q_SLOTS: - void onAngleChanged(double); - void onAxisChanged(int); - void onMidplane(bool); - void onReversed(bool); - -protected: - void onSelectionChanged(const Gui::SelectionChanges& msg) {} - void changeEvent(QEvent *e); - const bool updateView() const; - QString getReferenceAxis(void) const; - double getAngle(void) const; - bool getMidplane(void) const; - bool getReversed(void) const; - -private: - QWidget* proxy; - Ui_TaskRevolutionParameters* ui; -}; - -/// simulation dialog for the TaskView -class TaskDlgRevolutionParameters : public TaskDlgSketchBasedParameters -{ - Q_OBJECT - -public: - TaskDlgRevolutionParameters(ViewProviderRevolution *RevolutionView); - ~TaskDlgRevolutionParameters(); - - ViewProviderRevolution* getRevolutionView() const - { return static_cast(vp); } - -public: - /// is called by the framework if the dialog is accepted (Ok) - virtual bool accept(); -<<<<<<< 0973b40e8e489ddbf6455e9a2e80b0520f143b58 - /// is called by the framework if the dialog is rejected (Cancel) - virtual bool reject(); - virtual bool isAllowedAlterDocument(void) const - { return false; } - - /// returns for Close and Help button - virtual QDialogButtonBox::StandardButtons getStandardButtons(void) const - { return QDialogButtonBox::Ok|QDialogButtonBox::Cancel; } -======= ->>>>>>> Refactored code of SketchBased features to have common code in an abstract superclass - -protected: - TaskRevolutionParameters *parameter; -}; - -} //namespace PartDesignGui - -#endif // GUI_TASKVIEW_TASKAPPERANCE_H diff --git a/src/Mod/PartDesign/Gui/TaskScaledParameters.cpp.orig b/src/Mod/PartDesign/Gui/TaskScaledParameters.cpp.orig deleted file mode 100644 index a86768a21..000000000 --- a/src/Mod/PartDesign/Gui/TaskScaledParameters.cpp.orig +++ /dev/null @@ -1,273 +0,0 @@ -/****************************************************************************** - * Copyright (c)2012 Jan Rheinlaender * - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file COPYING.LIB. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * - ******************************************************************************/ - - -#include "PreCompiled.h" - -#ifndef _PreComp_ -# include -#endif - -#include "ui_TaskScaledParameters.h" -#include "TaskScaledParameters.h" -#include "TaskMultiTransformParameters.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace PartDesignGui; -using namespace Gui; - -/* TRANSLATOR PartDesignGui::TaskScaledParameters */ - -TaskScaledParameters::TaskScaledParameters(ViewProviderTransformed *TransformedView,QWidget *parent) - : TaskTransformedParameters(TransformedView, parent) -{ - // we need a separate container widget to add all controls to - proxy = new QWidget(this); - ui = new Ui_TaskScaledParameters(); - ui->setupUi(proxy); - QMetaObject::connectSlotsByName(this); - - this->groupLayout()->addWidget(proxy); - - ui->buttonOK->hide(); - ui->checkBoxUpdateView->setEnabled(true); - - blockUpdate = false; // Hack, sometimes it is NOT false although set to false in Transformed::Transformed()!! - setupUI(); -} - -TaskScaledParameters::TaskScaledParameters(TaskMultiTransformParameters *parentTask, QLayout *layout) - : TaskTransformedParameters(parentTask) -{ - proxy = new QWidget(parentTask); - ui = new Ui_TaskScaledParameters(); - ui->setupUi(proxy); - connect(ui->buttonOK, SIGNAL(pressed()), - parentTask, SLOT(onSubTaskButtonOK())); - QMetaObject::connectSlotsByName(this); - - layout->addWidget(proxy); - - ui->buttonOK->setEnabled(true); - ui->buttonAddFeature->hide(); - ui->buttonRemoveFeature->hide(); - ui->listWidgetFeatures->hide(); - ui->checkBoxUpdateView->hide(); - - blockUpdate = false; // Hack, sometimes it is NOT false although set to false in Transformed::Transformed()!! - setupUI(); -} - -void TaskScaledParameters::setupUI() -{ - connect(ui->buttonAddFeature, SIGNAL(toggled(bool)), this, SLOT(onButtonAddFeature(bool))); - connect(ui->buttonRemoveFeature, SIGNAL(toggled(bool)), this, SLOT(onButtonRemoveFeature(bool))); - // Create context menu - QAction* action = new QAction(tr("Remove"), this); - ui->listWidgetFeatures->addAction(action); - connect(action, SIGNAL(triggered()), this, SLOT(onFeatureDeleted())); - ui->listWidgetFeatures->setContextMenuPolicy(Qt::ActionsContextMenu); - - connect(ui->spinFactor, SIGNAL(valueChanged(double)), - this, SLOT(onFactor(double))); - connect(ui->spinOccurrences, SIGNAL(valueChanged(uint)), - this, SLOT(onOccurrences(uint))); - connect(ui->checkBoxUpdateView, SIGNAL(toggled(bool)), - this, SLOT(onUpdateView(bool))); - - // Get the feature data - PartDesign::Scaled* pcScaled = static_cast(getObject()); - std::vector originals = pcScaled->Originals.getValues(); - - // Fill data into dialog elements - for (std::vector::const_iterator i = originals.begin(); i != originals.end(); ++i) - { - if ((*i) != NULL) - ui->listWidgetFeatures->addItem(QString::fromLatin1((*i)->getNameInDocument())); - } - // --------------------- - - ui->spinFactor->bind(pcScaled->Factor); - ui->spinOccurrences->setMaximum(INT_MAX); - ui->spinOccurrences->bind(pcScaled->Occurrences); - ui->spinFactor->setEnabled(true); - ui->spinOccurrences->setEnabled(true); - //ui->spinFactor->setDecimals(Base::UnitsApi::getDecimals()); - - updateUI(); -} - -void TaskScaledParameters::updateUI() -{ - if (blockUpdate) - return; - blockUpdate = true; - - PartDesign::Scaled* pcScaled = static_cast(getObject()); - - double factor = pcScaled->Factor.getValue(); - unsigned occurrences = pcScaled->Occurrences.getValue(); - - ui->spinFactor->setValue(factor); - ui->spinOccurrences->setValue(occurrences); - - blockUpdate = false; -} - -void TaskScaledParameters::onSelectionChanged(const Gui::SelectionChanges& msg) -{ - if (originalSelected(msg)) { - if (selectionMode == addFeature) - ui->listWidgetFeatures->addItem(QString::fromLatin1(msg.pObjectName)); - else - removeItemFromListWidget(ui->listWidgetFeatures, msg.pObjectName); - exitSelectionMode(); - } -} - -void TaskScaledParameters::clearButtons() -{ - ui->buttonAddFeature->setChecked(false); - ui->buttonRemoveFeature->setChecked(false); -} - -void TaskScaledParameters::onFactor(const double f) -{ - if (blockUpdate) - return; - PartDesign::Scaled* pcScaled = static_cast(getObject()); - pcScaled->Factor.setValue(f); - recomputeFeature(); -} - -void TaskScaledParameters::onOccurrences(const uint n) -{ - if (blockUpdate) - return; - PartDesign::Scaled* pcScaled = static_cast(getObject()); - pcScaled->Occurrences.setValue(n); - recomputeFeature(); -} - -void TaskScaledParameters::onUpdateView(bool on) -{ - blockUpdate = !on; - if (on) { - // Do the same like in TaskDlgScaledParameters::accept() but without doCommand - PartDesign::Scaled* pcScaled = static_cast(getObject()); - pcScaled->Factor.setValue(getFactor()); - pcScaled->Occurrences.setValue(getOccurrences()); - recomputeFeature(); - } -} - -void TaskScaledParameters::onFeatureDeleted(void) -{ - PartDesign::Transformed* pcTransformed = getObject(); - std::vector originals = pcTransformed->Originals.getValues(); - originals.erase(originals.begin() + ui->listWidgetFeatures->currentRow()); - pcTransformed->Originals.setValues(originals); - ui->listWidgetFeatures->model()->removeRow(ui->listWidgetFeatures->currentRow()); - recomputeFeature(); -} - -const double TaskScaledParameters::getFactor(void) const -{ - return ui->spinFactor->value().getValue(); -} - -const unsigned TaskScaledParameters::getOccurrences(void) const -{ - return ui->spinOccurrences->value(); -} - -TaskScaledParameters::~TaskScaledParameters() -{ - delete ui; - if (proxy) - delete proxy; -} - -void TaskScaledParameters::changeEvent(QEvent *e) -{ - TaskBox::changeEvent(e); - if (e->type() == QEvent::LanguageChange) { - ui->retranslateUi(proxy); - } -} - -void TaskScaledParameters::apply() -{ - std::string name = TransformedView->getObject()->getNameInDocument(); - - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Factor = %f",name.c_str(), getFactor()); - ui->spinOccurrences->apply(); - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.recompute()"); - if (!TransformedView->getObject()->isValid()) - throw Base::Exception(TransformedView->getObject()->getStatusString()); - Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().resetEdit()"); - Gui::Command::commitCommand(); -} - -//************************************************************************** -//************************************************************************** -// TaskDialog -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -TaskDlgScaledParameters::TaskDlgScaledParameters(ViewProviderScaled *ScaledView) - : TaskDlgTransformedParameters(ScaledView) -{ - parameter = new TaskScaledParameters(ScaledView); - - Content.push_back(parameter); -} -//==== calls from the TaskView =============================================================== - -bool TaskDlgScaledParameters::accept() -{ - - parameter->apply(); -<<<<<<< a6aea83ec9ef83d52a06178b32175b3e79f73c65 - } - catch (const Base::Exception& e) { - QMessageBox::warning(parameter, tr("Input error"), QString::fromLatin1(e.what())); - return false; - } -======= ->>>>>>> PartDesign: make transform parameter dialogs use common base code with other dialogs - - return TaskDlgTransformedParameters::accept(); -} - -#include "moc_TaskScaledParameters.cpp" diff --git a/src/Mod/PartDesign/Gui/TaskTransformedParameters.cpp.orig b/src/Mod/PartDesign/Gui/TaskTransformedParameters.cpp.orig deleted file mode 100644 index f3bd2bbb7..000000000 --- a/src/Mod/PartDesign/Gui/TaskTransformedParameters.cpp.orig +++ /dev/null @@ -1,519 +0,0 @@ -/****************************************************************************** - * Copyright (c)2012 Jan Rheinlaender * - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file COPYING.LIB. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * - ******************************************************************************/ - -#include "PreCompiled.h" - -#ifndef _PreComp_ -# include -# include -# include -# include -# include -# include -#endif - -#include "TaskTransformedParameters.h" -#include "TaskMultiTransformParameters.h" -#include "Workbench.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "ReferenceSelection.h" - -using namespace PartDesignGui; -using namespace Gui; - -/* TRANSLATOR PartDesignGui::TaskTransformedParameters */ - -TaskTransformedParameters::TaskTransformedParameters(ViewProviderTransformed *TransformedView, QWidget *parent) - : TaskBox(Gui::BitmapFactory().pixmap((std::string("PartDesign_") + TransformedView->featureName).c_str()), - QString::fromLatin1((TransformedView->featureName + " parameters").c_str()), - true, - parent), - TransformedView(TransformedView), - parentTask(NULL), - insideMultiTransform(false), - blockUpdate(false) -{ - selectionMode = none; -} - -TaskTransformedParameters::TaskTransformedParameters(TaskMultiTransformParameters *parentTask) - : TaskBox(QPixmap(), tr(""), true, parentTask), - TransformedView(NULL), - parentTask(parentTask), - insideMultiTransform(true), - blockUpdate(false) -{ - // Original feature selection makes no sense inside a MultiTransform - selectionMode = none; -} - -TaskTransformedParameters::~TaskTransformedParameters() -{ - // make sure to remove selection gate in all cases - Gui::Selection().rmvSelectionGate(); -} - -bool TaskTransformedParameters::isViewUpdated() const -{ - return (blockUpdate == false); -} - -int TaskTransformedParameters::getUpdateViewTimeout() const -{ - return 500; -} - -const bool TaskTransformedParameters::originalSelected(const Gui::SelectionChanges& msg) -{ - if (msg.Type == Gui::SelectionChanges::AddSelection && ( - (selectionMode == addFeature) || (selectionMode == removeFeature))) { - - if (strcmp(msg.pDocName, getObject()->getDocument()->getName()) != 0) - return false; - - PartDesign::Transformed* pcTransformed = getObject(); - App::DocumentObject* selectedObject = pcTransformed->getDocument()->getObject(msg.pObjectName); - if (selectedObject->isDerivedFrom(PartDesign::FeatureAddSub::getClassTypeId())) { - - // Do the same like in TaskDlgTransformedParameters::accept() but without doCommand - std::vector originals = pcTransformed->Originals.getValues(); - std::vector::iterator o = std::find(originals.begin(), originals.end(), selectedObject); - if (selectionMode == addFeature) { - if (o == originals.end()) - originals.push_back(selectedObject); - else - return false; // duplicate selection - } else { - if (o != originals.end()) - originals.erase(o); - else - return false; - } - pcTransformed->Originals.setValues(originals); - recomputeFeature(); - - return true; - } - } - - return false; -} - -void TaskTransformedParameters::onButtonAddFeature(bool checked) -{ - if (checked) { - hideObject(); - showBase(); - selectionMode = addFeature; - Gui::Selection().clearSelection(); - } else { - exitSelectionMode(); - } -} - -void TaskTransformedParameters::onButtonRemoveFeature(bool checked) -{ - if (checked) { - hideObject(); - showBase(); - selectionMode = removeFeature; - Gui::Selection().clearSelection(); - } else { - exitSelectionMode(); - } -} - -void TaskTransformedParameters::removeItemFromListWidget(QListWidget* widget, const char* itemstr) -{ - QList items = widget->findItems(QString::fromAscii(itemstr), Qt::MatchExactly); - if (!items.empty()) { - for (QList::const_iterator i = items.begin(); i != items.end(); i++) { - QListWidgetItem* it = widget->takeItem(widget->row(*i)); - delete it; - } - } -} - - -App::DocumentObject* TaskTransformedParameters::getPartPlanes(const char* str) const { - //TODO: Adjust to GRAPH handling when available - App::DocumentObject* obj = getObject(); - App::Part* part = getPartFor(obj, false); - - if (part) { - std::vector origs = part->getObjectsOfType(App::Origin::getClassTypeId()); - if(origs.size()<1) - return nullptr; - - App::Origin* orig = static_cast(origs[0]); - auto planes = orig->getObjectsOfType(App::Plane::getClassTypeId()); - for(App::DocumentObject* plane : planes) { - if( strcmp(static_cast(plane)->PlaneType.getValue(), str) == 0) - return plane; - } - } - - return nullptr; -} - - -App::DocumentObject* TaskTransformedParameters::getPartLines(const char* str) const { - - //TODO: Adjust to GRAPH handling when available - App::DocumentObject* obj = getObject(); - App::Part* part = getPartFor(obj, false); - if (part) { - std::vector origs = part->getObjectsOfType(App::Origin::getClassTypeId()); - if(origs.size()<1) - return nullptr; - - App::Origin* orig = static_cast(origs[0]); - auto lines = orig->getObjectsOfType(App::Line::getClassTypeId()); - for(App::DocumentObject* line : lines) { - - if( strcmp(static_cast(line)->LineType.getValue(), str) == 0) - return line; - } - } - - return nullptr; -} - -void TaskTransformedParameters::fillAxisCombo(ComboLinks &combolinks, - Part::Part2DObject* sketch) -{ - combolinks.clear(); - - //add sketch axes - if (sketch){ - combolinks.addLink(sketch, "N_Axis",tr("Normal sketch axis")); - combolinks.addLink(sketch,"V_Axis",tr("Vertical sketch axis")); - combolinks.addLink(sketch,"H_Axis",tr("Horizontal sketch axis")); - for (int i=0; i < sketch->getAxisCount(); i++) { - QString itemText = tr("Construction line %1").arg(i+1); - std::stringstream sub; - sub << "Axis" << i; - combolinks.addLink(sketch,sub.str(),itemText); - } - } - - //add part axes - App::DocumentObject* line = 0; - line = getPartLines(App::Part::BaselineTypes[0]); - if(line) - combolinks.addLink(line,"",tr("Base X axis")); - line = getPartLines(App::Part::BaselineTypes[1]); - if(line) - combolinks.addLink(line,"",tr("Base Y axis")); - line = getPartLines(App::Part::BaselineTypes[2]); - if(line) - combolinks.addLink(line,"",tr("Base Z axis")); - - //add "Select reference" - combolinks.addLink(0,std::string(),tr("Select reference...")); -} - -void TaskTransformedParameters::fillPlanesCombo(ComboLinks &combolinks, - Part::Part2DObject* sketch) -{ - combolinks.clear(); - - //add sketch axes - if (sketch){ - combolinks.addLink(sketch,"V_Axis",QObject::tr("Vertical sketch axis")); - combolinks.addLink(sketch,"H_Axis",QObject::tr("Horizontal sketch axis")); - for (int i=0; i < sketch->getAxisCount(); i++) { - QString itemText = tr("Construction line %1").arg(i+1); - std::stringstream sub; - sub << "Axis" << i; - combolinks.addLink(sketch,sub.str(),itemText); - } - } - - //add part baseplanes - App::DocumentObject* plane = 0; - plane = getPartPlanes(App::Part::BaseplaneTypes[0]); - if(plane) - combolinks.addLink(plane,"",tr("Base XY plane")); - plane = getPartPlanes(App::Part::BaseplaneTypes[1]); - if(plane) - combolinks.addLink(plane,"",tr("Base XZ plane")); - plane = getPartPlanes(App::Part::BaseplaneTypes[2]); - if(plane) - combolinks.addLink(plane,"",tr("Base YZ plane")); - - //add "Select reference" - combolinks.addLink(0,std::string(),tr("Select reference...")); - -} - -void TaskTransformedParameters::recomputeFeature() { - getTopTransformedView()->recomputeFeature(); -} - -PartDesignGui::ViewProviderTransformed *TaskTransformedParameters::getTopTransformedView() const { - PartDesignGui::ViewProviderTransformed *rv; - - if (insideMultiTransform) { - rv = parentTask->TransformedView; - } else { - rv = TransformedView; - } - assert (rv); - - return rv; -} - -PartDesign::Transformed *TaskTransformedParameters::getTopTransformedObject() const { - App::DocumentObject *transform = getTopTransformedView()->getObject(); - assert (transform->isDerivedFrom(PartDesign::Transformed::getClassTypeId())); - return static_cast(transform); -} - - -PartDesign::Transformed *TaskTransformedParameters::getObject() const { - if (insideMultiTransform) - return parentTask->getSubFeature(); - else - return static_cast(TransformedView->getObject()); -} - -Part::Feature *TaskTransformedParameters::getBaseObject() const { - PartDesign::Feature* feature = getTopTransformedObject (); - // NOTE: getBaseObject() throws if there is no base; shouldn't happen here. - return feature->getBaseObject(); -} - -const std::vector & TaskTransformedParameters::getOriginals(void) const { - return getTopTransformedObject()->Originals.getValues(); -} - -App::DocumentObject* TaskTransformedParameters::getSketchObject() const { - return getTopTransformedObject()->getSketchObject(); -} - -void TaskTransformedParameters::hideObject() -{ - Gui::Document* doc = Gui::Application::Instance->activeDocument(); - if (doc) { - doc->setHide(getTopTransformedObject()->getNameInDocument()); - } -} - -void TaskTransformedParameters::showObject() -{ - Gui::Document* doc = Gui::Application::Instance->activeDocument(); - if (doc) { - doc->setShow(getTopTransformedObject()->getNameInDocument()); - } -} - -void TaskTransformedParameters::hideBase() -{ - Gui::Document* doc = Gui::Application::Instance->activeDocument(); - if (doc) { - try { - doc->setHide(getBaseObject()->getNameInDocument()); - } catch (const Base::Exception &) { } - } -} - -void TaskTransformedParameters::showBase() -{ - Gui::Document* doc = Gui::Application::Instance->activeDocument(); - if (doc) { - try { - doc->setShow(getBaseObject()->getNameInDocument()); - } catch (const Base::Exception &) { } - } -} - -void TaskTransformedParameters::exitSelectionMode() -{ - clearButtons(); - selectionMode = none; - Gui::Selection().rmvSelectionGate(); - showObject(); - hideBase(); -} - -void TaskTransformedParameters::addReferenceSelectionGate(bool edge, bool face) -{ - Gui::Selection().addSelectionGate(new ReferenceSelection(getBaseObject(), edge, face, /*point =*/ true)); -} - -//************************************************************************** -//************************************************************************** -// TaskDialog -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -TaskDlgTransformedParameters::TaskDlgTransformedParameters(ViewProviderTransformed *TransformedView_) - : TaskDlgFeatureParameters(TransformedView_) -{ - assert(vp); - message = new TaskTransformedMessages(getTransformedView()); - - Content.push_back(message); -} - -//==== calls from the TaskView =============================================================== - -bool TaskDlgTransformedParameters::accept() -{ -<<<<<<< a6aea83ec9ef83d52a06178b32175b3e79f73c65 - std::string name = TransformedView->getObject()->getNameInDocument(); - - try { - //Gui::Command::openCommand(featureName + " changed"); - std::vector originals = parameter->getOriginals(); - std::stringstream str; - str << "App.ActiveDocument." << name.c_str() << ".Originals = ["; - for (std::vector::const_iterator it = originals.begin(); it != originals.end(); ++it) - { - if ((*it) != NULL) - str << "App.ActiveDocument." << (*it)->getNameInDocument() << ","; - } - str << "]"; - Gui::Command::runCommand(Gui::Command::Doc,str.str().c_str()); - } - catch (const Base::Exception& e) { - QMessageBox::warning(parameter, tr("Input error"), QString::fromLatin1(e.what())); - return false; -======= - std::string name = vp->getObject()->getNameInDocument(); - - //Gui::Command::openCommand(featureName + " changed"); - std::vector originals = parameter->getOriginals(); - std::stringstream str; - str << "App.ActiveDocument." << name.c_str() << ".Originals = ["; - for (std::vector::const_iterator it = originals.begin(); it != originals.end(); ++it) - { - if ((*it) != NULL) - str << "App.ActiveDocument." << (*it)->getNameInDocument() << ","; ->>>>>>> PartDesign: make transform parameter dialogs use common base code with other dialogs - } - str << "]"; - Gui::Command::runCommand(Gui::Command::Doc,str.str().c_str()); - - // Continue (usually in virtual method accept()) - return TaskDlgFeatureParameters::accept (); -} - -bool TaskDlgTransformedParameters::reject() -{ - // ensure that we are not in selection mode - parameter->exitSelectionMode(); - - return TaskDlgFeatureParameters::reject (); -} - - -#include "moc_TaskTransformedParameters.cpp" - - -ComboLinks::ComboLinks(QComboBox &combo) - : doc(0) -{ - this->_combo = &combo; - _combo->clear(); -} - -int ComboLinks::addLink(const App::PropertyLinkSub &lnk, QString itemText) -{ - if(!_combo) - return 0; - _combo->addItem(itemText); - this->linksInList.push_back(new App::PropertyLinkSub()); - App::PropertyLinkSub &newitem = *(linksInList[linksInList.size()-1]); - newitem.Paste(lnk); - if (newitem.getValue() && this->doc == 0) - this->doc = newitem.getValue()->getDocument(); - return linksInList.size()-1; -} - -int ComboLinks::addLink(App::DocumentObject *linkObj, std::string linkSubname, QString itemText) -{ - if(!_combo) - return 0; - _combo->addItem(itemText); - this->linksInList.push_back(new App::PropertyLinkSub()); - App::PropertyLinkSub &newitem = *(linksInList[linksInList.size()-1]); - newitem.setValue(linkObj,std::vector(1,linkSubname)); - if (newitem.getValue() && this->doc == 0) - this->doc = newitem.getValue()->getDocument(); - return linksInList.size()-1; -} - -void ComboLinks::clear() -{ - for(int i = 0 ; i < this->linksInList.size() ; i++){ - delete linksInList[i]; - } - if(this->_combo) - _combo->clear(); -} - -App::PropertyLinkSub &ComboLinks::getLink(int index) const -{ - if (index < 0 || index > linksInList.size()-1) - throw Base::Exception("ComboLinks::getLink:Index out of range"); - if (linksInList[index]->getValue() && doc && !(doc->isIn(linksInList[index]->getValue()))) - throw Base::Exception("Linked object is not in the document; it may have been deleted"); - return *(linksInList[index]); -} - -App::PropertyLinkSub &ComboLinks::getCurrentLink() const -{ - assert(_combo); - return getLink(_combo->currentIndex()); -} - -int ComboLinks::setCurrentLink(const App::PropertyLinkSub &lnk) -{ - for(int i = 0 ; i < linksInList.size() ; i++) { - App::PropertyLinkSub &it = *(linksInList[i]); - if(lnk.getValue() == it.getValue() && lnk.getSubValues() == it.getSubValues()){ - bool wasBlocked = _combo->signalsBlocked(); - _combo->blockSignals(true); - _combo->setCurrentIndex(i); - _combo->blockSignals(wasBlocked); - return i; - } - } - return -1; -} diff --git a/src/Mod/PartDesign/Gui/TaskTransformedParameters.h.orig b/src/Mod/PartDesign/Gui/TaskTransformedParameters.h.orig deleted file mode 100644 index 209c7fcaa..000000000 --- a/src/Mod/PartDesign/Gui/TaskTransformedParameters.h.orig +++ /dev/null @@ -1,247 +0,0 @@ -/****************************************************************************** - * Copyright (c)2012 Jan Rheinlaender * - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file COPYING.LIB. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * - ******************************************************************************/ - - -#ifndef GUI_TASKVIEW_TaskTransformedParameters_H -#define GUI_TASKVIEW_TaskTransformedParameters_H - -#include - -#include - -#include -#include - -#include "TaskFeatureParameters.h" -#include "TaskTransformedMessages.h" -#include "ViewProviderTransformed.h" - -class QListWidget; - -namespace Part { -class Feature; -} - -namespace PartDesign { -class Transformed; -} - -namespace PartDesignGui { - -class TaskMultiTransformParameters; - -/** - * @brief The ComboLinks class is a helper class that binds to a combo box and - * provides an interface to add links, retrieve links and select items by link - * value - */ -class ComboLinks -{ -public: - /** - * @brief ComboLinks constructor. - * @param combo. It will be cleared as soon as it is bound. Don't add or - * remove items from the combo directly, otherwise internal tracking list - * will go out of sync, and crashes may result. - */ - ComboLinks(QComboBox &combo); - ComboLinks() {_combo = 0; doc = 0;}; - void setCombo(QComboBox &combo) {assert(_combo == 0); this->_combo = &combo; _combo->clear();} - - /** - * @brief addLink adds an item to the combo. Doesn't check for duplicates. - * @param lnk can be a link to NULL, which is usually used for special item "Select Reference" - * @param itemText - * @return - */ - int addLink(const App::PropertyLinkSub &lnk, QString itemText); - int addLink(App::DocumentObject* linkObj, std::string linkSubname, QString itemText); - void clear(); - App::PropertyLinkSub& getLink(int index) const; - - /** - * @brief getCurrentLink - * @return the link corresponding to the selected item. May be null link, - * which is usually used to indicate a "Select reference..." special item. - * Otherwise, the link is automatically tested for validity (oif an object - * doesn't exist in the document, an exception will be thrown.) - */ - App::PropertyLinkSub& getCurrentLink() const; - - /** - * @brief setCurrentLink selects the item with the link that matches the - * argument. If there is no such link in the list, -1 is returned and - * selected item is not changed. Signals from combo are blocked in this - * function. - * @param lnk - * @return the index of an item that was selected, -1 if link is not in the list yet. - */ - int setCurrentLink(const App::PropertyLinkSub &lnk); - - QComboBox& combo(void) const {assert(_combo); return *_combo;}; - - ~ComboLinks() {_combo = 0; clear();}; -private: - QComboBox* _combo; - App::Document* doc; - std::vector linksInList; -}; - -/** - The transformed subclasses will be used in two different modes: - 1. As a stand-alone feature - 2. As a container that stores transformation info for a MultiTransform feature. In this case - the flag insideMultiTransform is set to true. - Because in the second case there is no ViewProvider, some special methods are required to - access the underlying FeatureTransformed object in two different ways. - **/ -class TaskTransformedParameters : public Gui::TaskView::TaskBox, public Gui::SelectionObserver -{ - Q_OBJECT - -public: - /// Constructor for task with ViewProvider - TaskTransformedParameters(ViewProviderTransformed *TransformedView, QWidget *parent = 0); - /// Constructor for task with parent task (MultiTransform mode) - TaskTransformedParameters(TaskMultiTransformParameters *parentTask); - virtual ~TaskTransformedParameters(); - - /// Returns the originals property of associated top feeature object - const std::vector & getOriginals(void) const; - - /// Get the TransformedFeature object associated with this task - // Either through the ViewProvider or the currently active subFeature of the parentTask - Part::Feature *getBaseObject() const; - - /// Get the sketch object of the first original either of the object associated with this feature or with the parent feature (MultiTransform mode) - App::DocumentObject* getSketchObject() const; - - void exitSelectionMode(); - - virtual void apply() = 0; - -protected Q_SLOTS: - /** - * Returns the base transformation view provider - * For stand alone features it will be view provider associated with this object - * For features inside multitransform it will be the view provider of the multitransform object - */ - PartDesignGui::ViewProviderTransformed *getTopTransformedView () const; - - /** - * Returns the base transformated object - * For stand alone features it will be objects associated with this object - * For features inside multitransform it will be the base multitransform object - */ - PartDesign::Transformed *getTopTransformedObject () const; - - /// Connect the subTask OK button to the MultiTransform task - virtual void onSubTaskButtonOK() {} - void onButtonAddFeature(const bool checked); - void onButtonRemoveFeature(const bool checked); - virtual void onFeatureDeleted(void)=0; - -protected: - /** - * Returns the base transformation - * For stand alone features it will be objects associated with the view provider - * For features inside multitransform it will be the parent's multitransform object - */ - PartDesign::Transformed *getObject () const; - - const bool originalSelected(const Gui::SelectionChanges& msg); - - /// Recompute either this feature or the parent feature (MultiTransform mode) - void recomputeFeature(); - - void hideObject(); - void showObject(); - void hideBase(); - void showBase(); - - void addReferenceSelectionGate(bool edge, bool face); - - bool isViewUpdated() const; - int getUpdateViewTimeout() const; - -protected: - virtual void changeEvent(QEvent *e) = 0; - virtual void onSelectionChanged(const Gui::SelectionChanges& msg) = 0; - virtual void clearButtons()=0; - static void removeItemFromListWidget(QListWidget* widget, const char* itemstr); - - App::DocumentObject* getPartPlanes(const char* str) const; - App::DocumentObject* getPartLines(const char* str) const; - - void fillAxisCombo(ComboLinks &combolinks, Part::Part2DObject *sketch); - void fillPlanesCombo(ComboLinks &combolinks, Part2DObject *sketch); - -protected: - QWidget* proxy; - ViewProviderTransformed *TransformedView; - - enum selectionModes { none, addFeature, removeFeature, reference }; - selectionModes selectionMode; - - /// The MultiTransform parent task of this task - TaskMultiTransformParameters* parentTask; - /// Flag indicating whether this object is a container for MultiTransform - bool insideMultiTransform; - /// Lock updateUI(), applying changes to the underlying feature and calling recomputeFeature() - bool blockUpdate; -}; - -/// simulation dialog for the TaskView -class TaskDlgTransformedParameters : public PartDesignGui::TaskDlgFeatureParameters -{ - Q_OBJECT - -public: - TaskDlgTransformedParameters(ViewProviderTransformed *TransformedView); - virtual ~TaskDlgTransformedParameters() {} - - ViewProviderTransformed* getTransformedView() const - { return static_cast(vp); } - -public: - /// is called by the framework if the dialog is accepted (Ok) - virtual bool accept(); - /// is called by the framework if the dialog is rejected (Cancel) - virtual bool reject(); -<<<<<<< a6aea83ec9ef83d52a06178b32175b3e79f73c65 - virtual bool isAllowedAlterDocument(void) const - { return false; } - - /// returns for Close and Help button - virtual QDialogButtonBox::StandardButtons getStandardButtons(void) const - { return QDialogButtonBox::Ok|QDialogButtonBox::Cancel; } - -======= ->>>>>>> PartDesign: make transform parameter dialogs use common base code with other dialogs -protected: - TaskTransformedParameters *parameter; - TaskTransformedMessages *message; -}; - -} //namespace PartDesignGui - -#endif // GUI_TASKVIEW_TASKAPPERANCE_H diff --git a/src/Mod/PartDesign/Gui/ViewProviderTransformed.cpp.orig b/src/Mod/PartDesign/Gui/ViewProviderTransformed.cpp.orig deleted file mode 100644 index efe35658d..000000000 --- a/src/Mod/PartDesign/Gui/ViewProviderTransformed.cpp.orig +++ /dev/null @@ -1,410 +0,0 @@ -/****************************************************************************** - * Copyright (c)2012 Jan Rheinlaender * - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file COPYING.LIB. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * - ******************************************************************************/ - - -#include "PreCompiled.h" - -#ifndef _PreComp_ -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -#endif - -#include "Workbench.h" -#include "ViewProviderTransformed.h" -#include "TaskTransformedParameters.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace PartDesignGui; - -PROPERTY_SOURCE(PartDesignGui::ViewProviderTransformed,PartDesignGui::ViewProvider) - -void ViewProviderTransformed::setupContextMenu(QMenu* menu, QObject* receiver, const char* member) -{ - QAction* act; - act = menu->addAction(QObject::tr((std::string("Edit ") + featureName + " feature").c_str()), receiver, member); - act->setData(QVariant((int)ViewProvider::Default)); - PartGui::ViewProviderPart::setupContextMenu(menu, receiver, member); -} - -bool ViewProviderTransformed::setEdit(int ModNum) -{ - pcRejectedRoot = new SoSeparator(); - pcRejectedRoot->ref(); - - SoPickStyle* rejectedPickStyle = new SoPickStyle(); - rejectedPickStyle->style = SoPickStyle::UNPICKABLE; - - SoShapeHints* rejectedHints = new SoShapeHints(); - rejectedHints->vertexOrdering = SoShapeHints::COUNTERCLOCKWISE; - rejectedHints->shapeType = SoShapeHints::UNKNOWN_SHAPE_TYPE; - - SoMaterialBinding* rejectedBind = new SoMaterialBinding(); - - SoTransparencyType* rejectedTransparencyType = new SoTransparencyType(); - rejectedTransparencyType->value.setValue(SoGLRenderAction::BLEND); - - SoMaterial* rejectedMaterial = new SoMaterial(); - rejectedMaterial->diffuseColor.set1Value(0,SbColor(1.f,0.f,0.f)); - rejectedMaterial->transparency.setValue(0.6f); - - SoDrawStyle* rejectedFaceStyle = new SoDrawStyle(); - rejectedFaceStyle->style = SoDrawStyle::FILLED; - - SoNormalBinding* rejectedNormb = new SoNormalBinding(); - rejectedNormb->value = SoNormalBinding::PER_VERTEX_INDEXED; - - // just faces with no edges or points - pcRejectedRoot->addChild(rejectedPickStyle); - pcRejectedRoot->addChild(rejectedTransparencyType); - pcRejectedRoot->addChild(rejectedBind); - pcRejectedRoot->addChild(rejectedMaterial); - pcRejectedRoot->addChild(rejectedHints); - pcRejectedRoot->addChild(rejectedFaceStyle); - pcRejectedRoot->addChild(rejectedNormb); // NOTE: The code relies on the last child added here being index 6 - pcRoot->addChild(pcRejectedRoot); - - recomputeFeature(); - return true; -} - -void ViewProviderTransformed::unsetEdit(int ModNum) -{ - // return to the WB we were in before editing the PartDesign feature - Gui::Command::assureWorkbench(oldWb.c_str()); - - if (ModNum == ViewProvider::Default) { - // when pressing ESC make sure to close the dialog - Gui::Control().closeDialog(); - if ((PartDesignGui::ActivePartObject != NULL) && (oldTip != NULL)) { - Gui::Selection().clearSelection(); - Gui::Selection().addSelection(oldTip->getDocument()->getName(), oldTip->getNameInDocument()); - Gui::Command::doCommand(Gui::Command::Gui,"FreeCADGui.runCommand('PartDesign_MoveTip')"); - oldTip = NULL; - } else { - oldTip = NULL; - } - } - else { - PartGui::ViewProviderPart::unsetEdit(ModNum); - } - - while (pcRejectedRoot->getNumChildren() > 7) { - SoSeparator* sep = static_cast(pcRejectedRoot->getChild(7)); - SoMultipleCopy* rejectedTrfms = static_cast(sep->getChild(2)); - rejectedTrfms ->removeAllChildren(); - sep->removeChild(1); - sep->removeChild(0); - pcRejectedRoot ->removeChild(7); - } - pcRejectedRoot->removeAllChildren(); - - pcRoot->removeChild(pcRejectedRoot); - - pcRejectedRoot->unref(); -} - -bool ViewProviderTransformed::onDelete(const std::vector &s) -{ - return ViewProvider::onDelete(s); -} - -const bool ViewProviderTransformed::checkDlgOpen(TaskDlgTransformedParameters* transformedDlg) { - // When double-clicking on the item for this feature the - // object unsets and sets its edit mode without closing - // the task panel - Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog(); - transformedDlg = qobject_cast(dlg); - - if ((transformedDlg != NULL) && (transformedDlg->getTransformedView() != this)) - transformedDlg = NULL; // another transformed feature left open its task panel - - if ((dlg != NULL) && (transformedDlg == NULL)) { - QMessageBox msgBox; - msgBox.setText(QObject::tr("A dialog is already open in the task panel")); - msgBox.setInformativeText(QObject::tr("Do you want to close this dialog?")); - msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); - msgBox.setDefaultButton(QMessageBox::Yes); - int ret = msgBox.exec(); - if (ret == QMessageBox::Yes) - Gui::Control().reject(); - else - return false; - } - - // clear the selection (convenience) - Gui::Selection().clearSelection(); - - // Continue (usually in virtual method setEdit()) - return true; -} - -void ViewProviderTransformed::recomputeFeature(void) -{ - PartDesign::Transformed* pcTransformed = static_cast(getObject()); - pcTransformed->getDocument()->recomputeFeature(pcTransformed); - const std::vector log = pcTransformed->getDocument()->getRecomputeLog(); -<<<<<<< eb9a4ab96f8703de819cdc5e405217b784ccff90 - unsigned rejected = pcTransformed->getRejectedTransformations().size(); - QString msg = QString::fromLatin1("%1"); -======= - PartDesign::Transformed::rejectedMap rejected_trsf = pcTransformed->getRejectedTransformations(); - unsigned rejected = 0; - for (PartDesign::Transformed::rejectedMap::const_iterator r = rejected_trsf.begin(); r != rejected_trsf.end(); r++) - rejected += r->second.size(); - QString msg = QString::fromAscii("%1"); ->>>>>>> Enable multiple originals for the transformed features - if (rejected > 0) { - msg = QString::fromLatin1("%1
\r\n%2"); - if (rejected == 1) - msg = msg.arg(QObject::tr("One transformed shape does not intersect support")); - else { - msg = msg.arg(QObject::tr("%1 transformed shapes do not intersect support")); - msg = msg.arg(rejected); - } - } - if (log.size() > 0) { - msg = msg.arg(QString::fromLatin1("%1
")); - msg = msg.arg(QString::fromStdString(log.back()->Why)); - } else { - msg = msg.arg(QString::fromLatin1("%1
")); - msg = msg.arg(QObject::tr("Transformation succeeded")); - } - signalDiagnosis(msg); - - // Clear all the rejected stuff - while (pcRejectedRoot->getNumChildren() > 7) { - SoSeparator* sep = static_cast(pcRejectedRoot->getChild(7)); - SoMultipleCopy* rejectedTrfms = static_cast(sep->getChild(2)); - rejectedTrfms ->removeAllChildren(); - sep->removeChild(1); - sep->removeChild(0); - pcRejectedRoot ->removeChild(7); - } - - for (PartDesign::Transformed::rejectedMap::const_iterator o = rejected_trsf.begin(); o != rejected_trsf.end(); o++) { - if (o->second.empty()) continue; - - TopoDS_Shape shape; - if ((o->first)->getTypeId().isDerivedFrom(PartDesign::Additive::getClassTypeId())) { - PartDesign::Additive* addFeature = static_cast(o->first); - shape = addFeature->AddShape.getShape()._Shape; - } else if ((o->first)->getTypeId().isDerivedFrom(PartDesign::Subtractive::getClassTypeId())) { - PartDesign::Subtractive* subFeature = static_cast(o->first); - shape = subFeature->SubShape.getShape()._Shape; - } - - if (shape.IsNull()) continue; - - // Display the rejected transformations in red - TopoDS_Shape cShape(shape); - - try { - // calculating the deflection value - Standard_Real xMin, yMin, zMin, xMax, yMax, zMax; - { - Bnd_Box bounds; - BRepBndLib::Add(cShape, bounds); - bounds.SetGap(0.0); - bounds.Get(xMin, yMin, zMin, xMax, yMax, zMax); - } - Standard_Real deflection = ((xMax-xMin)+(yMax-yMin)+(zMax-zMin))/300.0 * Deviation.getValue(); - - // create or use the mesh on the data structure - // Note: This DOES have an effect on cShape -#if OCC_VERSION_HEX >= 0x060600 - Standard_Real AngDeflectionRads = AngularDeflection.getValue() / 180.0 * M_PI; - BRepMesh_IncrementalMesh(cShape,deflection,Standard_False, - AngDeflectionRads,Standard_True); -#else - BRepMesh_IncrementalMesh(cShape,deflection); -#endif - // We must reset the location here because the transformation data - // are set in the placement property - TopLoc_Location aLoc; - cShape.Location(aLoc); - - // count triangles and nodes in the mesh - int nbrTriangles=0, nbrNodes=0; - TopExp_Explorer Ex; - for (Ex.Init(cShape,TopAbs_FACE);Ex.More();Ex.Next()) { - Handle (Poly_Triangulation) mesh = BRep_Tool::Triangulation(TopoDS::Face(Ex.Current()), aLoc); - // Note: we must also count empty faces - if (!mesh.IsNull()) { - nbrTriangles += mesh->NbTriangles(); - nbrNodes += mesh->NbNodes(); - } - } - - // create memory for the nodes and indexes - SoCoordinate3* rejectedCoords = new SoCoordinate3(); - rejectedCoords ->point .setNum(nbrNodes); - SoNormal* rejectedNorms = new SoNormal(); - rejectedNorms ->vector .setNum(nbrNodes); - SoIndexedFaceSet* rejectedFaceSet = new SoIndexedFaceSet(); - rejectedFaceSet ->coordIndex .setNum(nbrTriangles*4); - - // get the raw memory for fast fill up - SbVec3f* verts = rejectedCoords ->point .startEditing(); - SbVec3f* norms = rejectedNorms ->vector .startEditing(); - int32_t* index = rejectedFaceSet ->coordIndex .startEditing(); - - // preset the normal vector with null vector - for (int i=0; i < nbrNodes; i++) - norms[i]= SbVec3f(0.0,0.0,0.0); - - int ii = 0,FaceNodeOffset=0,FaceTriaOffset=0; - for (Ex.Init(cShape, TopAbs_FACE); Ex.More(); Ex.Next(),ii++) { - TopLoc_Location aLoc; - const TopoDS_Face &actFace = TopoDS::Face(Ex.Current()); - // get the mesh of the shape - Handle (Poly_Triangulation) mesh = BRep_Tool::Triangulation(actFace,aLoc); - if (mesh.IsNull()) continue; - - // getting the transformation of the shape/face - gp_Trsf myTransf; - Standard_Boolean identity = true; - if (!aLoc.IsIdentity()) { - identity = false; - myTransf = aLoc.Transformation(); - } - - // getting size of node and triangle array of this face - int nbNodesInFace = mesh->NbNodes(); - int nbTriInFace = mesh->NbTriangles(); - // check orientation - TopAbs_Orientation orient = actFace.Orientation(); - - // cycling through the poly mesh - const Poly_Array1OfTriangle& Triangles = mesh->Triangles(); - const TColgp_Array1OfPnt& Nodes = mesh->Nodes(); - for (int g=1; g <= nbTriInFace; g++) { - // Get the triangle - Standard_Integer N1,N2,N3; - Triangles(g).Get(N1,N2,N3); - - // change orientation of the triangle if the face is reversed - if ( orient != TopAbs_FORWARD ) { - Standard_Integer tmp = N1; - N1 = N2; - N2 = tmp; - } - - // get the 3 points of this triangle - gp_Pnt V1(Nodes(N1)), V2(Nodes(N2)), V3(Nodes(N3)); - - // transform the vertices to the place of the face - if (!identity) { - V1.Transform(myTransf); - V2.Transform(myTransf); - V3.Transform(myTransf); - } - - // calculating per vertex normals - // Calculate triangle normal - gp_Vec v1(V1.X(),V1.Y(),V1.Z()),v2(V2.X(),V2.Y(),V2.Z()),v3(V3.X(),V3.Y(),V3.Z()); - gp_Vec Normal = (v2-v1)^(v3-v1); - - // add the triangle normal to the vertex normal for all points of this triangle - norms[FaceNodeOffset+N1-1] += SbVec3f(Normal.X(),Normal.Y(),Normal.Z()); - norms[FaceNodeOffset+N2-1] += SbVec3f(Normal.X(),Normal.Y(),Normal.Z()); - norms[FaceNodeOffset+N3-1] += SbVec3f(Normal.X(),Normal.Y(),Normal.Z()); - - // set the vertices - verts[FaceNodeOffset+N1-1].setValue((float)(V1.X()),(float)(V1.Y()),(float)(V1.Z())); - verts[FaceNodeOffset+N2-1].setValue((float)(V2.X()),(float)(V2.Y()),(float)(V2.Z())); - verts[FaceNodeOffset+N3-1].setValue((float)(V3.X()),(float)(V3.Y()),(float)(V3.Z())); - - // set the index vector with the 3 point indexes and the end delimiter - index[FaceTriaOffset*4+4*(g-1)] = FaceNodeOffset+N1-1; - index[FaceTriaOffset*4+4*(g-1)+1] = FaceNodeOffset+N2-1; - index[FaceTriaOffset*4+4*(g-1)+2] = FaceNodeOffset+N3-1; - index[FaceTriaOffset*4+4*(g-1)+3] = SO_END_FACE_INDEX; - } - - // counting up the per Face offsets - FaceNodeOffset += nbNodesInFace; - FaceTriaOffset += nbTriInFace; - } - - // normalize all normals - for (int i=0; i < nbrNodes; i++) - norms[i].normalize(); - - // end the editing of the nodes - rejectedCoords ->point .finishEditing(); - rejectedNorms ->vector .finishEditing(); - rejectedFaceSet ->coordIndex .finishEditing(); - - // fill in the transformation matrices - SoMultipleCopy* rejectedTrfms = new SoMultipleCopy(); - rejectedTrfms->matrix.setNum((o->second).size()); - SbMatrix* mats = rejectedTrfms->matrix.startEditing(); - - std::list::const_iterator trsf = (o->second).begin(); - for (unsigned int i=0; i < (o->second).size(); i++,trsf++) { - Base::Matrix4D mat; - Part::TopoShape::convertToMatrix(*trsf,mat); - mats[i] = convert(mat); - } - rejectedTrfms->matrix.finishEditing(); - rejectedTrfms->addChild(rejectedFaceSet); - SoSeparator* sep = new SoSeparator(); - sep->addChild(rejectedCoords); - sep->addChild(rejectedNorms); - sep->addChild(rejectedTrfms); - pcRejectedRoot->addChild(sep); - } - catch (...) { - Base::Console().Error("Cannot compute Inventor representation for the rejected transformations of shape of %s.\n", - pcTransformed->getNameInDocument()); - } - } - -} - diff --git a/src/Mod/PartDesign/InitGui.py.orig b/src/Mod/PartDesign/InitGui.py.orig deleted file mode 100644 index 06a1f693d..000000000 --- a/src/Mod/PartDesign/InitGui.py.orig +++ /dev/null @@ -1,76 +0,0 @@ -# PartDesign gui init module -# (c) 2003 Juergen Riegel -# -# Gathering all the information to start FreeCAD -# This is the second one of three init scripts, the third one -# runs when the gui is up - -#*************************************************************************** -#* (c) Juergen Riegel (juergen.riegel@web.de) 2002 * -#* * -#* This file is part of the FreeCAD CAx development system. * -#* * -#* This program is free software; you can redistribute it and/or modify * -#* it under the terms of the GNU Lesser General Public License (LGPL) * -#* as published by the Free Software Foundation; either version 2 of * -#* the License, or (at your option) any later version. * -#* for detail see the LICENCE text file. * -#* * -#* FreeCAD is distributed in the hope that it will be useful, * -#* but WITHOUT ANY WARRANTY; without even the implied warranty of * -#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -#* GNU Lesser General Public License for more details. * -#* * -#* You should have received a copy of the GNU Library General Public * -#* License along with FreeCAD; if not, write to the Free Software * -#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * -#* USA * -#* * -#* Juergen Riegel 2002 * -#***************************************************************************/ - -class PartDesignWorkbench ( Workbench ): - "PartDesign workbench object" - def __init__(self): - self.__class__.Icon = FreeCAD.getResourceDir() + "Mod/PartDesign/Resources/icons/PartDesignWorkbench.svg" - self.__class__.MenuText = "Part Design" - self.__class__.ToolTip = "Part Design workbench" - - def Initialize(self): - # load the module - try: - from WizardShaft import WizardShaft - except ImportError: - print "Wizard shaft module cannot be loaded" - try: - from FeatureHole import HoleGui - except: - pass -<<<<<<< b5588a8b68f0650311b83fab5cf5afffd31f9a5f - import PartDesignGui - import PartDesign - try: - import InvoluteGearFeature - except ImportError: - print "Involute gear module cannot be loaded" - try: - from FeatureHole import HoleGui - except: - pass -======= - import PartDesignGui - import PartDesign - try: - import InvoluteGearFeature - except ImportError: - print "Involute gear module cannot be loaded" - #try: - # from FeatureHole import HoleGui - #except: - # pass ->>>>>>> remove hole feature - - def GetClassName(self): - return "PartDesignGui::Workbench" - -Gui.addWorkbench(PartDesignWorkbench()) diff --git a/src/Mod/Sketcher/App/SketchObject.cpp.orig b/src/Mod/Sketcher/App/SketchObject.cpp.orig deleted file mode 100644 index b3180b83a..000000000 --- a/src/Mod/Sketcher/App/SketchObject.cpp.orig +++ /dev/null @@ -1,4180 +0,0 @@ -/*************************************************************************** -<<<<<<< ef369d31e9c7931d6b64b7c59697c263887085f8 - * Copyright (c) Jürgen Riegel (juergen.riegel@web.de) 2008 * -======= - * Copyright (c) Juergen Riegel (juergen.riegel@web.de) 2008 * ->>>>>>> Moved generic Datum class to Part module to avoid Sketcher dependency on PartDesign - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file COPYING.LIB. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * - ***************************************************************************/ - - -#include "PreCompiled.h" -#ifndef _PreComp_ -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -#endif // #ifndef _PreComp_ - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include "SketchObject.h" -#include "SketchObjectPy.h" -#include "Sketch.h" - -using namespace Sketcher; -using namespace Base; - - -PROPERTY_SOURCE(Sketcher::SketchObject, Part::Part2DObject) - - -SketchObject::SketchObject() -{ - ADD_PROPERTY_TYPE(Geometry, (0) ,"Sketch",(App::PropertyType)(App::Prop_None),"Sketch geometry"); - ADD_PROPERTY_TYPE(Constraints, (0) ,"Sketch",(App::PropertyType)(App::Prop_None),"Sketch constraints"); - ADD_PROPERTY_TYPE(ExternalGeometry,(0,0),"Sketch",(App::PropertyType)(App::Prop_None),"Sketch external geometry"); - - for (std::vector::iterator it=ExternalGeo.begin(); it != ExternalGeo.end(); ++it) - if (*it) delete *it; - ExternalGeo.clear(); - Part::GeomLineSegment *HLine = new Part::GeomLineSegment(); - Part::GeomLineSegment *VLine = new Part::GeomLineSegment(); - HLine->setPoints(Base::Vector3d(0,0,0),Base::Vector3d(1,0,0)); - VLine->setPoints(Base::Vector3d(0,0,0),Base::Vector3d(0,1,0)); - HLine->Construction = true; - VLine->Construction = true; - ExternalGeo.push_back(HLine); - ExternalGeo.push_back(VLine); - rebuildVertexIndex(); - - lastDoF=0; - lastHasConflict=false; - lastHasRedundancies=false; - lastSolverStatus=0; - lastSolveTime=0; - - solverNeedsUpdate=false; - - noRecomputes=false; - - ExpressionEngine.setValidator(boost::bind(&Sketcher::SketchObject::validateExpression, this, _1, _2)); - - constraintsRemovedConn = Constraints.signalConstraintsRemoved.connect(boost::bind(&Sketcher::SketchObject::constraintsRemoved, this, _1)); - constraintsRenamedConn = Constraints.signalConstraintsRenamed.connect(boost::bind(&Sketcher::SketchObject::constraintsRenamed, this, _1)); -} - -SketchObject::~SketchObject() -{ - for (std::vector::iterator it=ExternalGeo.begin(); it != ExternalGeo.end(); ++it) - if (*it) delete *it; - ExternalGeo.clear(); -} - -App::DocumentObjectExecReturn *SketchObject::execute(void) -{ - try { - App::DocumentObject* support = Support.getValue(); - if (support == NULL) - throw Base::Exception("Sketch support has been deleted"); - - this->positionBySupport(); - } - catch (const Base::Exception& e) { - return new App::DocumentObjectExecReturn(e.what()); - } - - // setup and diagnose the sketch - try { - rebuildExternalGeometry(); - } - catch (const Base::Exception& e) { - Base::Console().Error("%s\nClear constraints to external geometry\n", e.what()); - // we cannot trust the constraints of external geometries, so remove them - delConstraintsToExternal(); - } - - // We should have an updated Sketcher geometry or this execute should not have happened - // therefore we update our sketch object geometry with the SketchObject one. - // - // set up a sketch (including dofs counting and diagnosing of conflicts) - lastDoF = solvedSketch.setUpSketch(getCompleteGeometry(), Constraints.getValues(), - getExternalGeometryCount()); - lastHasConflict = solvedSketch.hasConflicts(); - lastHasRedundancies = solvedSketch.hasRedundancies(); - lastConflicting=solvedSketch.getConflicting(); - lastRedundant=solvedSketch.getRedundant(); - - lastSolveTime=0.0; - lastSolverStatus=GCS::Failed; // Failure is default for notifying the user unless otherwise proven - - solverNeedsUpdate=false; - - if (lastDoF < 0) { // over-constrained sketch - std::string msg="Over-constrained sketch\n"; - appendConflictMsg(lastConflicting, msg); - return new App::DocumentObjectExecReturn(msg.c_str(),this); - } - if (lastHasConflict) { // conflicting constraints - std::string msg="Sketch with conflicting constraints\n"; - appendConflictMsg(lastConflicting, msg); - return new App::DocumentObjectExecReturn(msg.c_str(),this); - } - if (lastHasRedundancies) { // redundant constraints - std::string msg="Sketch with redundant constraints\n"; - appendRedundantMsg(lastRedundant, msg); - return new App::DocumentObjectExecReturn(msg.c_str(),this); - } - // solve the sketch - lastSolverStatus=solvedSketch.solve(); - lastSolveTime=solvedSketch.SolveTime; - - if (lastSolverStatus != 0) - return new App::DocumentObjectExecReturn("Solving the sketch failed",this); - - std::vector geomlist = solvedSketch.extractGeometry(); - Geometry.setValues(geomlist); - for (std::vector::iterator it=geomlist.begin(); it != geomlist.end(); ++it) - if (*it) delete *it; - - // this is not necessary for sketch representation in edit mode, unless we want to trigger an update of - // the objects that depend on this sketch (like pads) - Shape.setValue(solvedSketch.toShape()); - - return App::DocumentObject::StdReturn; -} - -int SketchObject::hasConflicts(void) const -{ - if (lastDoF < 0) // over-constrained sketch - return -2; - if (solvedSketch.hasConflicts()) // conflicting constraints - return -1; - - return 0; -} - -int SketchObject::solve(bool updateGeoAfterSolving/*=true*/) -{ - // if updateGeoAfterSolving=false, the solver information is updated, but the Sketch is nothing - // updated. It is useful to avoid triggering an OnChange when the goeometry did not change but - // the solver needs to be updated. - - // We should have an updated Sketcher geometry or this solver should not have happened - // therefore we update our sketch object geometry with the SketchObject one. - // - // set up a sketch (including dofs counting and diagnosing of conflicts) - lastDoF = solvedSketch.setUpSketch(getCompleteGeometry(), Constraints.getValues(), - getExternalGeometryCount()); - - solverNeedsUpdate=false; - - lastHasConflict = solvedSketch.hasConflicts(); - - int err=0; - if (lastDoF < 0) { // over-constrained sketch - err = -3; - // if lastDoF<0, then an over-constrained situation has ensued. - // Geometry is not to be updated, as geometry can not follow the constraints. - // However, solver information must be updated. - this->Constraints.touch(); - } - else if (lastHasConflict) { // conflicting constraints - err = -3; - } - else { - lastSolverStatus=solvedSketch.solve(); - if (lastSolverStatus != 0){ // solving - err = -2; - // if solver failed, geometry was never updated, but invalid constraints were likely added before - // solving (see solve in addConstraint), so solver information is definitely invalid. - this->Constraints.touch(); - - } - - } - - lastHasRedundancies = solvedSketch.hasRedundancies(); - - lastConflicting=solvedSketch.getConflicting(); - lastRedundant=solvedSketch.getRedundant(); - lastSolveTime=solvedSketch.SolveTime; - - if (err == 0 && updateGeoAfterSolving) { - // set the newly solved geometry - std::vector geomlist = solvedSketch.extractGeometry(); - Geometry.setValues(geomlist); - for (std::vector::iterator it = geomlist.begin(); it != geomlist.end(); ++it) - if (*it) delete *it; - } - - return err; -} - -int SketchObject::setDatum(int ConstrId, double Datum) -{ - // set the changed value for the constraint - const std::vector &vals = this->Constraints.getValues(); - if (ConstrId < 0 || ConstrId >= int(vals.size())) - return -1; - ConstraintType type = vals[ConstrId]->Type; - if (type != Distance && - type != DistanceX && - type != DistanceY && - type != Radius && - type != Angle && - type != Tangent && //for tangent, value==0 is autodecide, value==Pi/2 is external and value==-Pi/2 is internal - type != Perpendicular && - type != SnellsLaw) - return -1; - - if ((type == Distance || type == Radius) && Datum <= 0) - return (Datum == 0) ? -5 : -4; - - // copy the list - std::vector newVals(vals); - // clone the changed Constraint - Constraint *constNew = vals[ConstrId]->clone(); - constNew->setValue(Datum); - newVals[ConstrId] = constNew; - this->Constraints.setValues(newVals); - delete constNew; - - int err = solve(); - if (err) - this->Constraints.setValues(vals); - - return err; -} - -int SketchObject::setDriving(int ConstrId, bool isdriving) -{ - const std::vector &vals = this->Constraints.getValues(); - - if (ConstrId < 0 || ConstrId >= int(vals.size())) - return -1; - - ConstraintType type = vals[ConstrId]->Type; - - if (type != Distance && - type != DistanceX && - type != DistanceY && - type != Radius && - type != Angle && - type != SnellsLaw) - return -2; - - if (!(vals[ConstrId]->First>=0 || vals[ConstrId]->Second>=0 || vals[ConstrId]->Third>=0) && isdriving==true) - return -3; // a constraint that does not have at least one element as not-external-geometry can never be driving. - - // copy the list - std::vector newVals(vals); - // clone the changed Constraint - Constraint *constNew = vals[ConstrId]->clone(); - constNew->isDriving = isdriving; - newVals[ConstrId] = constNew; - this->Constraints.setValues(newVals); - if (isdriving) - setExpression(Constraints.createPath(ConstrId), boost::shared_ptr()); - delete constNew; - - if(noRecomputes) // if we do not have a recompute, the sketch must be solved to update the DoF of the solver - solve(); - - return 0; -} - -int SketchObject::getDriving(int ConstrId, bool &isdriving) -{ - const std::vector &vals = this->Constraints.getValues(); - - if (ConstrId < 0 || ConstrId >= int(vals.size())) - return -1; - - ConstraintType type = vals[ConstrId]->Type; - - if (type != Distance && - type != DistanceX && - type != DistanceY && - type != Radius && - type != Angle && - type != SnellsLaw) - return -1; - - isdriving=vals[ConstrId]->isDriving; - return 0; -} - -int SketchObject::toggleDriving(int ConstrId) -{ - const std::vector &vals = this->Constraints.getValues(); - - if (ConstrId < 0 || ConstrId >= int(vals.size())) - return -1; - - ConstraintType type = vals[ConstrId]->Type; - - if (type != Distance && - type != DistanceX && - type != DistanceY && - type != Radius && - type != Angle && - type != SnellsLaw) - return -2; - - if (!(vals[ConstrId]->First>=0 || vals[ConstrId]->Second>=0 || vals[ConstrId]->Third>=0) && vals[ConstrId]->isDriving==false) - return -3; // a constraint that does not have at least one element as not-external-geometry can never be driving. - - // copy the list - std::vector newVals(vals); - // clone the changed Constraint - Constraint *constNew = vals[ConstrId]->clone(); - constNew->isDriving = !constNew->isDriving; - newVals[ConstrId] = constNew; - this->Constraints.setValues(newVals); - if (constNew->isDriving) - setExpression(Constraints.createPath(ConstrId), boost::shared_ptr()); - delete constNew; - - if(noRecomputes) // if we do not have a recompute, the sketch must be solved to update the DoF of the solver - solve(); - - return 0; -} - -int SketchObject::setUpSketch() -{ - return solvedSketch.setUpSketch(getCompleteGeometry(), Constraints.getValues(), - getExternalGeometryCount()); -} - -int SketchObject::movePoint(int GeoId, PointPos PosId, const Base::Vector3d& toPoint, bool relative, bool updateGeoBeforeMoving) -{ - // if we are moving a point at SketchObject level, we need to start from a solved sketch - // if we have conflicts we can forget about moving. However, there is the possibility that we - // need to do programatically moves of new geometry that has not been solved yet and that because - // they were programmetically generated won't generate a conflict. This is the case of Fillet for - // example. This is why exceptionally, it may be required to update the sketch geometry to that of - // of SketchObject upon moving. => use updateGeometry parameter = true then - - - if(updateGeoBeforeMoving || solverNeedsUpdate) { - lastDoF = solvedSketch.setUpSketch(getCompleteGeometry(), Constraints.getValues(), - getExternalGeometryCount()); - - lastHasConflict = solvedSketch.hasConflicts(); - lastHasRedundancies = solvedSketch.hasRedundancies(); - lastConflicting=solvedSketch.getConflicting(); - lastRedundant=solvedSketch.getRedundant(); - - solverNeedsUpdate=false; - } - - if (lastDoF < 0) // over-constrained sketch - return -1; - if (lastHasConflict) // conflicting constraints - return -1; - - // move the point and solve - lastSolverStatus = solvedSketch.movePoint(GeoId, PosId, toPoint, relative); - - // moving the point can not result in a conflict that we did not have - // or a redundancy that we did not have before, or a change of DoF - - if (lastSolverStatus == 0) { - std::vector geomlist = solvedSketch.extractGeometry(); - Geometry.setValues(geomlist); - //Constraints.acceptGeometry(getCompleteGeometry()); - for (std::vector::iterator it=geomlist.begin(); it != geomlist.end(); ++it) { - if (*it) delete *it; - } - } - - return lastSolverStatus; -} - -Base::Vector3d SketchObject::getPoint(int GeoId, PointPos PosId) const -{ - if(!(GeoId == H_Axis || GeoId == V_Axis - || (GeoId <= getHighestCurveIndex() && GeoId >= -getExternalGeometryCount()) )) - throw Base::Exception("SketchObject::getPoint. Invalid GeoId was supplied."); - const Part::Geometry *geo = getGeometry(GeoId); - if (geo->getTypeId() == Part::GeomPoint::getClassTypeId()) { - const Part::GeomPoint *p = dynamic_cast(geo); - if (PosId == start || PosId == mid || PosId == end) - return p->getPoint(); - } else if (geo->getTypeId() == Part::GeomLineSegment::getClassTypeId()) { - const Part::GeomLineSegment *lineSeg = dynamic_cast(geo); - if (PosId == start) - return lineSeg->getStartPoint(); - else if (PosId == end) - return lineSeg->getEndPoint(); - } else if (geo->getTypeId() == Part::GeomCircle::getClassTypeId()) { - const Part::GeomCircle *circle = dynamic_cast(geo); - if (PosId == mid) - return circle->getCenter(); - } else if (geo->getTypeId() == Part::GeomEllipse::getClassTypeId()) { - const Part::GeomEllipse *ellipse = dynamic_cast(geo); - if (PosId == mid) - return ellipse->getCenter(); - } else if (geo->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()) { - const Part::GeomArcOfCircle *aoc = dynamic_cast(geo); - if (PosId == start) - return aoc->getStartPoint(/*emulateCCW=*/true); - else if (PosId == end) - return aoc->getEndPoint(/*emulateCCW=*/true); - else if (PosId == mid) - return aoc->getCenter(); - } else if (geo->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId()) { - const Part::GeomArcOfEllipse *aoc = dynamic_cast(geo); - if (PosId == start) - return aoc->getStartPoint(/*emulateCCW=*/true); - else if (PosId == end) - return aoc->getEndPoint(/*emulateCCW=*/true); - else if (PosId == mid) - return aoc->getCenter(); - } - - return Base::Vector3d(); -} - -int SketchObject::getAxisCount(void) const -{ - const std::vector< Part::Geometry * > &vals = getInternalGeometry(); - - int count=0; - for (std::vector::const_iterator geo=vals.begin(); - geo != vals.end(); geo++) - if ((*geo) && (*geo)->Construction && - (*geo)->getTypeId() == Part::GeomLineSegment::getClassTypeId()) - count++; - - return count; -} - -Base::Axis SketchObject::getAxis(int axId) const -{ - if (axId == H_Axis || axId == V_Axis || axId == N_Axis) - return Part::Part2DObject::getAxis(axId); - - const std::vector< Part::Geometry * > &vals = getInternalGeometry(); - int count=0; - for (std::vector::const_iterator geo=vals.begin(); - geo != vals.end(); geo++) - if ((*geo) && (*geo)->Construction && - (*geo)->getTypeId() == Part::GeomLineSegment::getClassTypeId()) { - if (count == axId) { - Part::GeomLineSegment *lineSeg = dynamic_cast(*geo); - Base::Vector3d start = lineSeg->getStartPoint(); - Base::Vector3d end = lineSeg->getEndPoint(); - return Base::Axis(start, end-start); - } - count++; - } - - return Base::Axis(); -} - -void SketchObject::acceptGeometry() -{ - Constraints.acceptGeometry(getCompleteGeometry()); - rebuildVertexIndex(); -} - -bool SketchObject::isSupportedGeometry(const Part::Geometry *geo) const -{ - if (geo->getTypeId() == Part::GeomPoint::getClassTypeId() || - geo->getTypeId() == Part::GeomCircle::getClassTypeId() || - geo->getTypeId() == Part::GeomEllipse::getClassTypeId() || - geo->getTypeId() == Part::GeomArcOfCircle::getClassTypeId() || - geo->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId() || - geo->getTypeId() == Part::GeomLineSegment::getClassTypeId()) { - return true; - } - if (geo->getTypeId() == Part::GeomTrimmedCurve::getClassTypeId()) { - Handle_Geom_TrimmedCurve trim = Handle_Geom_TrimmedCurve::DownCast(geo->handle()); - Handle_Geom_Circle circle = Handle_Geom_Circle::DownCast(trim->BasisCurve()); - Handle_Geom_Ellipse ellipse = Handle_Geom_Ellipse::DownCast(trim->BasisCurve()); - if (!circle.IsNull() || !ellipse.IsNull()) { - return true; - } - } - return false; -} - -std::vector SketchObject::supportedGeometry(const std::vector &geoList) const -{ - std::vector supportedGeoList; - supportedGeoList.reserve(geoList.size()); - // read-in geometry that the sketcher cannot handle - for (std::vector::const_iterator it = geoList.begin(); it != geoList.end(); ++it) { - if (isSupportedGeometry(*it)) { - supportedGeoList.push_back(*it); - } - } - - return supportedGeoList; -} - -int SketchObject::addGeometry(const std::vector &geoList, bool construction/*=false*/) -{ - const std::vector< Part::Geometry * > &vals = getInternalGeometry(); - - std::vector< Part::Geometry * > newVals(vals); - for (std::vector::const_iterator it = geoList.begin(); it != geoList.end(); ++it) { - if(construction && (*it)->getTypeId() != Part::GeomPoint::getClassTypeId()) - const_cast(*it)->Construction = construction; - - newVals.push_back(*it); - } - Geometry.setValues(newVals); - Constraints.acceptGeometry(getCompleteGeometry()); - rebuildVertexIndex(); - - return Geometry.getSize()-1; -} - -int SketchObject::addGeometry(const Part::Geometry *geo, bool construction/*=false*/) -{ - const std::vector< Part::Geometry * > &vals = getInternalGeometry(); - - std::vector< Part::Geometry * > newVals(vals); - Part::Geometry *geoNew = geo->clone(); - - if(geoNew->getTypeId() != Part::GeomPoint::getClassTypeId()) - geoNew->Construction = construction; - - newVals.push_back(geoNew); - Geometry.setValues(newVals); - Constraints.acceptGeometry(getCompleteGeometry()); - delete geoNew; - rebuildVertexIndex(); - - return Geometry.getSize()-1; -} - -int SketchObject::delGeometry(int GeoId) -{ - const std::vector< Part::Geometry * > &vals = getInternalGeometry(); - if (GeoId < 0 || GeoId >= int(vals.size())) - return -1; - - this->DeleteUnusedInternalGeometry(GeoId); - - std::vector< Part::Geometry * > newVals(vals); - newVals.erase(newVals.begin()+GeoId); - - // Find coincident points to replace the points of the deleted geometry - std::vector GeoIdList; - std::vector PosIdList; - for (PointPos PosId = start; PosId != mid; ) { - getDirectlyCoincidentPoints(GeoId, PosId, GeoIdList, PosIdList); - if (GeoIdList.size() > 1) { - delConstraintOnPoint(GeoId, PosId, true /* only coincidence */); - transferConstraints(GeoIdList[0], PosIdList[0], GeoIdList[1], PosIdList[1]); - } - PosId = (PosId == start) ? end : mid; // loop through [start, end, mid] - } - - const std::vector< Constraint * > &constraints = this->Constraints.getValues(); - std::vector< Constraint * > newConstraints(0); - for (std::vector::const_iterator it = constraints.begin(); - it != constraints.end(); ++it) { - if ((*it)->First != GeoId && (*it)->Second != GeoId && (*it)->Third != GeoId) { - Constraint *copiedConstr = (*it)->clone(); - if (copiedConstr->First > GeoId) - copiedConstr->First -= 1; - if (copiedConstr->Second > GeoId) - copiedConstr->Second -= 1; - if (copiedConstr->Third > GeoId) - copiedConstr->Third -= 1; - newConstraints.push_back(copiedConstr); - } - } - - this->Geometry.setValues(newVals); - this->Constraints.setValues(newConstraints); - this->Constraints.acceptGeometry(getCompleteGeometry()); - rebuildVertexIndex(); - - if(noRecomputes) // if we do not have a recompute, the sketch must be solved to update the DoF of the solver - solve(); - - return 0; -} - -int SketchObject::toggleConstruction(int GeoId) -{ - const std::vector< Part::Geometry * > &vals = getInternalGeometry(); - if (GeoId < 0 || GeoId >= int(vals.size())) - return -1; - - std::vector< Part::Geometry * > newVals(vals); - - Part::Geometry *geoNew = newVals[GeoId]->clone(); - geoNew->Construction = !geoNew->Construction; - newVals[GeoId]=geoNew; - - this->Geometry.setValues(newVals); - //this->Constraints.acceptGeometry(getCompleteGeometry()); <= This is not necessary for a toggle. Reducing redundant solving. Abdullah - solverNeedsUpdate=true; - return 0; -} - -int SketchObject::setConstruction(int GeoId, bool on) -{ - const std::vector< Part::Geometry * > &vals = getInternalGeometry(); - if (GeoId < 0 || GeoId >= int(vals.size())) - return -1; - - std::vector< Part::Geometry * > newVals(vals); - - Part::Geometry *geoNew = newVals[GeoId]->clone(); - geoNew->Construction = on; - newVals[GeoId]=geoNew; - - this->Geometry.setValues(newVals); - //this->Constraints.acceptGeometry(getCompleteGeometry()); <= This is not necessary for a toggle. Reducing redundant solving. Abdullah - solverNeedsUpdate=true; - return 0; -} - -//ConstraintList is used only to make copies. -int SketchObject::addConstraints(const std::vector &ConstraintList) -{ - const std::vector< Constraint * > &vals = this->Constraints.getValues(); - - std::vector< Constraint * > newVals(vals); - newVals.insert(newVals.end(), ConstraintList.begin(), ConstraintList.end()); - - //test if tangent constraints have been added; AutoLockTangency. - std::vector< Constraint * > tbd;//list of temporary copies that need to be deleted - for(std::size_t i = newVals.size()-ConstraintList.size(); iType == Tangent || newVals[i]->Type == Perpendicular ){ - Constraint *constNew = newVals[i]->clone(); - AutoLockTangencyAndPerpty(constNew); - tbd.push_back(constNew); - newVals[i] = constNew; - } - } - - this->Constraints.setValues(newVals); - - //clean up - delete temporary copies of constraints that were made to affect the constraints - for(std::size_t i=0; iConstraints.getSize()-1; -} - -int SketchObject::addConstraint(const Constraint *constraint) -{ - const std::vector< Constraint * > &vals = this->Constraints.getValues(); - - std::vector< Constraint * > newVals(vals); - Constraint *constNew = constraint->clone(); - - if (constNew->Type == Tangent || constNew->Type == Perpendicular) - AutoLockTangencyAndPerpty(constNew); - - newVals.push_back(constNew); - this->Constraints.setValues(newVals); - delete constNew; - return this->Constraints.getSize()-1; -} - -int SketchObject::delConstraint(int ConstrId) -{ - const std::vector< Constraint * > &vals = this->Constraints.getValues(); - if (ConstrId < 0 || ConstrId >= int(vals.size())) - return -1; - - std::vector< Constraint * > newVals(vals); - newVals.erase(newVals.begin()+ConstrId); - this->Constraints.setValues(newVals); - - if(noRecomputes) // if we do not have a recompute, the sketch must be solved to update the DoF of the solver - solve(); - - return 0; -} - -int SketchObject::delConstraintOnPoint(int VertexId, bool onlyCoincident) -{ - int GeoId; - PointPos PosId; - if (VertexId == -1) { // RootPoint - GeoId = -1; - PosId = start; - } else - getGeoVertexIndex(VertexId, GeoId, PosId); - - return delConstraintOnPoint(GeoId, PosId, onlyCoincident); -} - -int SketchObject::delConstraintOnPoint(int GeoId, PointPos PosId, bool onlyCoincident) -{ - const std::vector &vals = this->Constraints.getValues(); - - // check if constraints can be redirected to some other point - int replaceGeoId=Constraint::GeoUndef; - PointPos replacePosId=Sketcher::none; - if (!onlyCoincident) { - for (std::vector::const_iterator it = vals.begin(); it != vals.end(); ++it) { - if ((*it)->Type == Sketcher::Coincident) { - if ((*it)->First == GeoId && (*it)->FirstPos == PosId) { - replaceGeoId = (*it)->Second; - replacePosId = (*it)->SecondPos; - break; - } - else if ((*it)->Second == GeoId && (*it)->SecondPos == PosId) { - replaceGeoId = (*it)->First; - replacePosId = (*it)->FirstPos; - break; - } - } - } - } - - // remove or redirect any constraints associated with the given point - std::vector newVals(0); - for (std::vector::const_iterator it = vals.begin(); it != vals.end(); ++it) { - if ((*it)->Type == Sketcher::Coincident) { - if ((*it)->First == GeoId && (*it)->FirstPos == PosId) { - if (replaceGeoId != Constraint::GeoUndef && - (replaceGeoId != (*it)->Second || replacePosId != (*it)->SecondPos)) { // redirect this constraint - (*it)->First = replaceGeoId; - (*it)->FirstPos = replacePosId; - } - else - continue; // skip this constraint - } - else if ((*it)->Second == GeoId && (*it)->SecondPos == PosId) { - if (replaceGeoId != Constraint::GeoUndef && - (replaceGeoId != (*it)->First || replacePosId != (*it)->FirstPos)) { // redirect this constraint - (*it)->Second = replaceGeoId; - (*it)->SecondPos = replacePosId; - } - else - continue; // skip this constraint - } - } - else if (!onlyCoincident) { - if ((*it)->Type == Sketcher::Distance || - (*it)->Type == Sketcher::DistanceX || (*it)->Type == Sketcher::DistanceY) { - if ((*it)->First == GeoId && (*it)->FirstPos == none && - (PosId == start || PosId == end)) { - // remove the constraint even if it is not directly associated - // with the given point - continue; // skip this constraint - } - else if ((*it)->First == GeoId && (*it)->FirstPos == PosId) { - if (replaceGeoId != Constraint::GeoUndef) { // redirect this constraint - (*it)->First = replaceGeoId; - (*it)->FirstPos = replacePosId; - } - else - continue; // skip this constraint - } - else if ((*it)->Second == GeoId && (*it)->SecondPos == PosId) { - if (replaceGeoId != Constraint::GeoUndef) { // redirect this constraint - (*it)->Second = replaceGeoId; - (*it)->SecondPos = replacePosId; - } - else - continue; // skip this constraint - } - } - else if ((*it)->Type == Sketcher::PointOnObject) { - if ((*it)->First == GeoId && (*it)->FirstPos == PosId) { - if (replaceGeoId != Constraint::GeoUndef) { // redirect this constraint - (*it)->First = replaceGeoId; - (*it)->FirstPos = replacePosId; - } - else - continue; // skip this constraint - } - } - else if ((*it)->Type == Sketcher::Tangent) { - if (((*it)->First == GeoId && (*it)->FirstPos == PosId) || - ((*it)->Second == GeoId && (*it)->SecondPos == PosId)) { - // we could keep the tangency constraint by converting it - // to a simple one but it is not really worth - continue; // skip this constraint - } - } - else if ((*it)->Type == Sketcher::Symmetric) { - if (((*it)->First == GeoId && (*it)->FirstPos == PosId) || - ((*it)->Second == GeoId && (*it)->SecondPos == PosId)) { - continue; // skip this constraint - } - } - } - newVals.push_back(*it); - } - if (newVals.size() < vals.size()) { - this->Constraints.setValues(newVals); - - return 0; - } - - return -1; // no such constraint -} - -int SketchObject::transferConstraints(int fromGeoId, PointPos fromPosId, int toGeoId, PointPos toPosId) -{ - const std::vector &vals = this->Constraints.getValues(); - std::vector newVals(vals); - for (int i=0; i < int(newVals.size()); i++) { - if (vals[i]->First == fromGeoId && vals[i]->FirstPos == fromPosId && - !(vals[i]->Second == toGeoId && vals[i]->SecondPos == toPosId)) { - Constraint *constNew = newVals[i]->clone(); - constNew->First = toGeoId; - constNew->FirstPos = toPosId; - newVals[i] = constNew; - } else if (vals[i]->Second == fromGeoId && vals[i]->SecondPos == fromPosId && - !(vals[i]->First == toGeoId && vals[i]->FirstPos == toPosId)) { - Constraint *constNew = newVals[i]->clone(); - constNew->Second = toGeoId; - constNew->SecondPos = toPosId; - newVals[i] = constNew; - } - } - this->Constraints.setValues(newVals); - return 0; -} - -int SketchObject::fillet(int GeoId, PointPos PosId, double radius, bool trim) -{ - if (GeoId < 0 || GeoId > getHighestCurveIndex()) - return -1; - - // Find the other geometry Id associated with the coincident point - std::vector GeoIdList; - std::vector PosIdList; - getDirectlyCoincidentPoints(GeoId, PosId, GeoIdList, PosIdList); - - // only coincident points between two (non-external) edges can be filleted - if (GeoIdList.size() == 2 && GeoIdList[0] >= 0 && GeoIdList[1] >= 0) { - const Part::Geometry *geo1 = getGeometry(GeoIdList[0]); - const Part::Geometry *geo2 = getGeometry(GeoIdList[1]); - if (geo1->getTypeId() == Part::GeomLineSegment::getClassTypeId() && - geo2->getTypeId() == Part::GeomLineSegment::getClassTypeId() ) { - const Part::GeomLineSegment *lineSeg1 = dynamic_cast(geo1); - const Part::GeomLineSegment *lineSeg2 = dynamic_cast(geo2); - - Base::Vector3d midPnt1 = (lineSeg1->getStartPoint() + lineSeg1->getEndPoint()) / 2 ; - Base::Vector3d midPnt2 = (lineSeg2->getStartPoint() + lineSeg2->getEndPoint()) / 2 ; - return fillet(GeoIdList[0], GeoIdList[1], midPnt1, midPnt2, radius, trim); - } - } - - return -1; -} - -int SketchObject::fillet(int GeoId1, int GeoId2, - const Base::Vector3d& refPnt1, const Base::Vector3d& refPnt2, - double radius, bool trim) -{ - if (GeoId1 < 0 || GeoId1 > getHighestCurveIndex() || - GeoId2 < 0 || GeoId2 > getHighestCurveIndex()) - return -1; - - const Part::Geometry *geo1 = getGeometry(GeoId1); - const Part::Geometry *geo2 = getGeometry(GeoId2); - if (geo1->getTypeId() == Part::GeomLineSegment::getClassTypeId() && - geo2->getTypeId() == Part::GeomLineSegment::getClassTypeId() ) { - const Part::GeomLineSegment *lineSeg1 = dynamic_cast(geo1); - const Part::GeomLineSegment *lineSeg2 = dynamic_cast(geo2); - - Base::Vector3d filletCenter; - if (!Part::findFilletCenter(lineSeg1, lineSeg2, radius, refPnt1, refPnt2, filletCenter)) - return -1; - Base::Vector3d dir1 = lineSeg1->getEndPoint() - lineSeg1->getStartPoint(); - Base::Vector3d dir2 = lineSeg2->getEndPoint() - lineSeg2->getStartPoint(); - - // the intersection point will and two distances will be necessary later for trimming the lines - Base::Vector3d intersection, dist1, dist2; - - // create arc from known parameters and lines - int filletId; - Part::GeomArcOfCircle *arc = Part::createFilletGeometry(lineSeg1, lineSeg2, filletCenter, radius); - if (arc) { - // calculate intersection and distances before we invalidate lineSeg1 and lineSeg2 - if (!find2DLinesIntersection(lineSeg1, lineSeg2, intersection)) { - delete arc; - return -1; - } - dist1.ProjToLine(arc->getStartPoint(/*emulateCCW=*/true)-intersection, dir1); - dist2.ProjToLine(arc->getStartPoint(/*emulateCCW=*/true)-intersection, dir2); - Part::Geometry *newgeo = dynamic_cast(arc); - filletId = addGeometry(newgeo); - if (filletId < 0) { - delete arc; - return -1; - } - } - else - return -1; - - if (trim) { - PointPos PosId1 = (filletCenter-intersection)*dir1 > 0 ? start : end; - PointPos PosId2 = (filletCenter-intersection)*dir2 > 0 ? start : end; - - delConstraintOnPoint(GeoId1, PosId1, false); - delConstraintOnPoint(GeoId2, PosId2, false); - Sketcher::Constraint *tangent1 = new Sketcher::Constraint(); - Sketcher::Constraint *tangent2 = new Sketcher::Constraint(); - - tangent1->Type = Sketcher::Tangent; - tangent1->First = GeoId1; - tangent1->FirstPos = PosId1; - tangent1->Second = filletId; - - tangent2->Type = Sketcher::Tangent; - tangent2->First = GeoId2; - tangent2->FirstPos = PosId2; - tangent2->Second = filletId; - - if (dist1.Length() < dist2.Length()) { - tangent1->SecondPos = start; - tangent2->SecondPos = end; - movePoint(GeoId1, PosId1, arc->getStartPoint(/*emulateCCW=*/true),false,true); - movePoint(GeoId2, PosId2, arc->getEndPoint(/*emulateCCW=*/true),false,true); - } - else { - tangent1->SecondPos = end; - tangent2->SecondPos = start; - movePoint(GeoId1, PosId1, arc->getEndPoint(/*emulateCCW=*/true),false,true); - movePoint(GeoId2, PosId2, arc->getStartPoint(/*emulateCCW=*/true),false,true); - } - - addConstraint(tangent1); - addConstraint(tangent2); - delete tangent1; - delete tangent2; - } - delete arc; - - if(noRecomputes) // if we do not have a recompute after the geometry creation, the sketch must be solved to update the DoF of the solver - solve(); - - return 0; - } - return -1; -} - -int SketchObject::trim(int GeoId, const Base::Vector3d& point) -{ - if (GeoId < 0 || GeoId > getHighestCurveIndex()) - return -1; - - const std::vector &geomlist = getInternalGeometry(); - const std::vector &constraints = this->Constraints.getValues(); - - int GeoId1=Constraint::GeoUndef, GeoId2=Constraint::GeoUndef; - Base::Vector3d point1, point2; - Part2DObject::seekTrimPoints(geomlist, GeoId, point, GeoId1, point1, GeoId2, point2); - if (GeoId1 < 0 && GeoId2 >= 0) { - std::swap(GeoId1,GeoId2); - std::swap(point1,point2); - } - - Part::Geometry *geo = geomlist[GeoId]; - if (geo->getTypeId() == Part::GeomLineSegment::getClassTypeId()) { - const Part::GeomLineSegment *lineSeg = dynamic_cast(geo); - Base::Vector3d startPnt = lineSeg->getStartPoint(); - Base::Vector3d endPnt = lineSeg->getEndPoint(); - Base::Vector3d dir = (endPnt - startPnt).Normalize(); - double length = (endPnt - startPnt)*dir; - double x0 = (point - startPnt)*dir; - if (GeoId1 >= 0 && GeoId2 >= 0) { - double x1 = (point1 - startPnt)*dir; - double x2 = (point2 - startPnt)*dir; - if (x1 > x2) { - std::swap(GeoId1,GeoId2); - std::swap(point1,point2); - std::swap(x1,x2); - } - if (x1 >= 0.001*length && x2 <= 0.999*length) { - if (x1 < x0 && x2 > x0) { - int newGeoId = addGeometry(geo); - // go through all constraints and replace the point (GeoId,end) with (newGeoId,end) - transferConstraints(GeoId, end, newGeoId, end); - - movePoint(GeoId, end, point1,false,true); - movePoint(newGeoId, start, point2,false,true); - - PointPos secondPos1 = Sketcher::none, secondPos2 = Sketcher::none; - ConstraintType constrType1 = Sketcher::PointOnObject, constrType2 = Sketcher::PointOnObject; - for (std::vector::const_iterator it=constraints.begin(); - it != constraints.end(); ++it) { - Constraint *constr = *(it); - if (secondPos1 == Sketcher::none && (constr->First == GeoId1 && constr->Second == GeoId)) { - constrType1= Sketcher::Coincident; - secondPos1 = constr->FirstPos; - } else if (secondPos2 == Sketcher::none && (constr->First == GeoId2 && constr->Second == GeoId)) { - constrType2 = Sketcher::Coincident; - secondPos2 = constr->FirstPos; - } - } - - // constrain the trimming points on the corresponding geometries - Sketcher::Constraint *newConstr = new Sketcher::Constraint(); - newConstr->Type = constrType1; - newConstr->First = GeoId; - newConstr->FirstPos = end; - newConstr->Second = GeoId1; - - if (constrType1 == Sketcher::Coincident) { - newConstr->SecondPos = secondPos1; - delConstraintOnPoint(GeoId1, secondPos1, false); - } - - addConstraint(newConstr); - - // Reset the second pos - newConstr->SecondPos = Sketcher::none; - - newConstr->Type = constrType2; - newConstr->First = newGeoId; - newConstr->FirstPos = start; - newConstr->Second = GeoId2; - - if (constrType2 == Sketcher::Coincident) { - newConstr->SecondPos = secondPos2; - delConstraintOnPoint(GeoId2, secondPos2, false); - } - - addConstraint(newConstr); - - // Reset the second pos - newConstr->SecondPos = Sketcher::none; - - // new line segments colinear - newConstr->Type = Sketcher::Tangent; - newConstr->First = GeoId; - newConstr->FirstPos = none; - newConstr->Second = newGeoId; - addConstraint(newConstr); - delete newConstr; - - if(noRecomputes) // if we do not have a recompute, the sketch must be solved to update the DoF of the solver - solve(); - - return 0; - } - } else if (x1 < 0.001*length) { // drop the first intersection point - std::swap(GeoId1,GeoId2); - std::swap(point1,point2); - } else if (x2 > 0.999*length) { // drop the second intersection point - } - else - return -1; - } - - if (GeoId1 >= 0) { - double x1 = (point1 - startPnt)*dir; - if (x1 >= 0.001*length && x1 <= 0.999*length) { - - ConstraintType constrType = Sketcher::PointOnObject; - PointPos secondPos = Sketcher::none; - for (std::vector::const_iterator it=constraints.begin(); - it != constraints.end(); ++it) { - Constraint *constr = *(it); - if ((constr->First == GeoId1 && constr->Second == GeoId)) { - constrType = Sketcher::Coincident; - secondPos = constr->FirstPos; - delConstraintOnPoint(GeoId1, constr->FirstPos, false); - break; - } - } - - if (x1 > x0) { // trim line start - delConstraintOnPoint(GeoId, start, false); - movePoint(GeoId, start, point1,false,true); - - // constrain the trimming point on the corresponding geometry - Sketcher::Constraint *newConstr = new Sketcher::Constraint(); - newConstr->Type = constrType; - newConstr->First = GeoId; - newConstr->FirstPos = start; - newConstr->Second = GeoId1; - - if (constrType == Sketcher::Coincident) - newConstr->SecondPos = secondPos; - - addConstraint(newConstr); - delete newConstr; - - if(noRecomputes) // if we do not have a recompute, the sketch must be solved to update the DoF of the solver - solve(); - - return 0; - } - else if (x1 < x0) { // trim line end - delConstraintOnPoint(GeoId, end, false); - movePoint(GeoId, end, point1,false,true); - Sketcher::Constraint *newConstr = new Sketcher::Constraint(); - newConstr->Type = constrType; - newConstr->First = GeoId; - newConstr->FirstPos = end; - newConstr->Second = GeoId1; - - if (constrType == Sketcher::Coincident) - newConstr->SecondPos = secondPos; - - addConstraint(newConstr); - delete newConstr; - - if(noRecomputes) // if we do not have a recompute, the sketch must be solved to update the DoF of the solver - solve(); - - return 0; - } - } - } - } else if (geo->getTypeId() == Part::GeomCircle::getClassTypeId()) { - const Part::GeomCircle *circle = dynamic_cast(geo); - Base::Vector3d center = circle->getCenter(); - double theta0 = Base::fmod(atan2(point.y - center.y,point.x - center.x), 2.f*M_PI); - if (GeoId1 >= 0 && GeoId2 >= 0) { - double theta1 = Base::fmod(atan2(point1.y - center.y, point1.x - center.x), 2.f*M_PI); - double theta2 = Base::fmod(atan2(point2.y - center.y, point2.x - center.x), 2.f*M_PI); - if (Base::fmod(theta1 - theta0, 2.f*M_PI) > Base::fmod(theta2 - theta0, 2.f*M_PI)) { - std::swap(GeoId1,GeoId2); - std::swap(point1,point2); - std::swap(theta1,theta2); - } - if (theta1 == theta0 || theta1 == theta2) - return -1; - else if (theta1 > theta2) - theta2 += 2.f*M_PI; - - // Trim Point between intersection points - - // Create a new arc to substitute Circle in geometry list and set parameters - Part::GeomArcOfCircle *geoNew = new Part::GeomArcOfCircle(); - geoNew->setCenter(center); - geoNew->setRadius(circle->getRadius()); - geoNew->setRange(theta1, theta2,/*emulateCCW=*/true); - - std::vector< Part::Geometry * > newVals(geomlist); - newVals[GeoId] = geoNew; - Geometry.setValues(newVals); - Constraints.acceptGeometry(getCompleteGeometry()); - delete geoNew; - rebuildVertexIndex(); - - PointPos secondPos1 = Sketcher::none, secondPos2 = Sketcher::none; - ConstraintType constrType1 = Sketcher::PointOnObject, constrType2 = Sketcher::PointOnObject; - for (std::vector::const_iterator it=constraints.begin(); - it != constraints.end(); ++it) { - Constraint *constr = *(it); - if (secondPos1 == Sketcher::none && (constr->First == GeoId1 && constr->Second == GeoId)) { - constrType1= Sketcher::Coincident; - secondPos1 = constr->FirstPos; - } else if(secondPos2 == Sketcher::none && (constr->First == GeoId2 && constr->Second == GeoId)) { - constrType2 = Sketcher::Coincident; - secondPos2 = constr->FirstPos; - } - } - - // constrain the trimming points on the corresponding geometries - Sketcher::Constraint *newConstr = new Sketcher::Constraint(); - newConstr->Type = constrType1; - newConstr->First = GeoId; - newConstr->FirstPos = start; - newConstr->Second = GeoId1; - - if (constrType1 == Sketcher::Coincident) { - newConstr->SecondPos = secondPos1; - delConstraintOnPoint(GeoId1, secondPos1, false); - } - - addConstraint(newConstr); - - // Reset secondpos in case it was set previously - newConstr->SecondPos = Sketcher::none; - - // Add Second Constraint - newConstr->First = GeoId; - newConstr->FirstPos = end; - newConstr->Second = GeoId2; - - if (constrType2 == Sketcher::Coincident) { - newConstr->SecondPos = secondPos2; - delConstraintOnPoint(GeoId2, secondPos2, false); - } - - addConstraint(newConstr); - - delete newConstr; - - if(noRecomputes) // if we do not have a recompute, the sketch must be solved to update the DoF of the solver - solve(); - - return 0; - } - } else if (geo->getTypeId() == Part::GeomEllipse::getClassTypeId()) { - const Part::GeomEllipse *ellipse = dynamic_cast(geo); - Base::Vector3d center = ellipse->getCenter(); - double theta0; - ellipse->closestParameter(point,theta0); - theta0 = Base::fmod(theta0, 2.f*M_PI); - if (GeoId1 >= 0 && GeoId2 >= 0) { - double theta1; - ellipse->closestParameter(point1,theta1); - theta1 = Base::fmod(theta1, 2.f*M_PI); - double theta2; - ellipse->closestParameter(point2,theta2); - theta2 = Base::fmod(theta2, 2.f*M_PI); - if (Base::fmod(theta1 - theta0, 2.f*M_PI) > Base::fmod(theta2 - theta0, 2.f*M_PI)) { - std::swap(GeoId1,GeoId2); - std::swap(point1,point2); - std::swap(theta1,theta2); - } - if (theta1 == theta0 || theta1 == theta2) - return -1; - else if (theta1 > theta2) - theta2 += 2.f*M_PI; - - // Trim Point between intersection points - - // Create a new arc to substitute Circle in geometry list and set parameters - Part::GeomArcOfEllipse *geoNew = new Part::GeomArcOfEllipse(); - geoNew->setCenter(center); - geoNew->setMajorRadius(ellipse->getMajorRadius()); - geoNew->setMinorRadius(ellipse->getMinorRadius()); - geoNew->setMajorAxisDir(ellipse->getMajorAxisDir()); - geoNew->setRange(theta1, theta2, /*emulateCCW=*/true); - - std::vector< Part::Geometry * > newVals(geomlist); - newVals[GeoId] = geoNew; - Geometry.setValues(newVals); - Constraints.acceptGeometry(getCompleteGeometry()); - delete geoNew; - rebuildVertexIndex(); - - PointPos secondPos1 = Sketcher::none, secondPos2 = Sketcher::none; - ConstraintType constrType1 = Sketcher::PointOnObject, constrType2 = Sketcher::PointOnObject; - for (std::vector::const_iterator it=constraints.begin(); - it != constraints.end(); ++it) { - Constraint *constr = *(it); - if (secondPos1 == Sketcher::none && (constr->First == GeoId1 && constr->Second == GeoId)) { - constrType1= Sketcher::Coincident; - secondPos1 = constr->FirstPos; - } else if(secondPos2 == Sketcher::none && (constr->First == GeoId2 && constr->Second == GeoId)) { - constrType2 = Sketcher::Coincident; - secondPos2 = constr->FirstPos; - } - } - - // constrain the trimming points on the corresponding geometries - Sketcher::Constraint *newConstr = new Sketcher::Constraint(); - newConstr->Type = constrType1; - newConstr->First = GeoId; - newConstr->FirstPos = start; - newConstr->Second = GeoId1; - - if (constrType1 == Sketcher::Coincident) { - newConstr->SecondPos = secondPos1; - delConstraintOnPoint(GeoId1, secondPos1, false); - } - - addConstraint(newConstr); - - // Reset secondpos in case it was set previously - newConstr->SecondPos = Sketcher::none; - - // Add Second Constraint - newConstr->First = GeoId; - newConstr->FirstPos = end; - newConstr->Second = GeoId2; - - if (constrType2 == Sketcher::Coincident) { - newConstr->SecondPos = secondPos2; - delConstraintOnPoint(GeoId2, secondPos2, false); - } - - addConstraint(newConstr); - - delete newConstr; - - if(noRecomputes) // if we do not have a recompute, the sketch must be solved to update the DoF of the solver - solve(); - - return 0; - } - } else if (geo->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()) { - const Part::GeomArcOfCircle *aoc = dynamic_cast(geo); - Base::Vector3d center = aoc->getCenter(); - double startAngle, endAngle; - aoc->getRange(startAngle, endAngle, /*emulateCCW=*/true); - double dir = (startAngle < endAngle) ? 1 : -1; // this is always == 1 - double arcLength = (endAngle - startAngle)*dir; - double theta0 = Base::fmod(atan2(point.y - center.y, point.x - center.x) - startAngle, 2.f*M_PI); // x0 - if (GeoId1 >= 0 && GeoId2 >= 0) { - double theta1 = Base::fmod(atan2(point1.y - center.y, point1.x - center.x) - startAngle, 2.f*M_PI) * dir; // x1 - double theta2 = Base::fmod(atan2(point2.y - center.y, point2.x - center.x) - startAngle, 2.f*M_PI) * dir; // x2 - if (theta1 > theta2) { - std::swap(GeoId1,GeoId2); - std::swap(point1,point2); - std::swap(theta1,theta2); - } - if (theta1 >= 0.001*arcLength && theta2 <= 0.999*arcLength) { - // Trim Point between intersection points - if (theta1 < theta0 && theta2 > theta0) { - int newGeoId = addGeometry(geo); - // go through all constraints and replace the point (GeoId,end) with (newGeoId,end) - transferConstraints(GeoId, end, newGeoId, end); - - Part::GeomArcOfCircle *aoc1 = dynamic_cast(geomlist[GeoId]); - Part::GeomArcOfCircle *aoc2 = dynamic_cast(geomlist[newGeoId]); - aoc1->setRange(startAngle, startAngle + theta1, /*emulateCCW=*/true); - aoc2->setRange(startAngle + theta2, endAngle, /*emulateCCW=*/true); - - // constrain the trimming points on the corresponding geometries - Sketcher::Constraint *newConstr = new Sketcher::Constraint(); - - // Build Constraints associated with new pair of arcs - newConstr->Type = Sketcher::Equal; - newConstr->First = GeoId; - newConstr->Second = newGeoId; - addConstraint(newConstr); - - PointPos secondPos1 = Sketcher::none, secondPos2 = Sketcher::none; - ConstraintType constrType1 = Sketcher::PointOnObject, constrType2 = Sketcher::PointOnObject; - - for (std::vector::const_iterator it=constraints.begin(); - it != constraints.end(); ++it) { - Constraint *constr = *(it); - if (secondPos1 == Sketcher::none && - (constr->First == GeoId1 && constr->Second == GeoId)) { - constrType1= Sketcher::Coincident; - secondPos1 = constr->FirstPos; - } else if (secondPos2 == Sketcher::none && - (constr->First == GeoId2 && constr->Second == GeoId)) { - constrType2 = Sketcher::Coincident; - secondPos2 = constr->FirstPos; - } - } - - newConstr->Type = constrType1; - newConstr->First = GeoId; - newConstr->FirstPos = end; - newConstr->Second = GeoId1; - - if (constrType1 == Sketcher::Coincident) { - newConstr->SecondPos = secondPos1; - delConstraintOnPoint(GeoId1, secondPos1, false); - } - - addConstraint(newConstr); - - // Reset secondpos in case it was set previously - newConstr->SecondPos = Sketcher::none; - - newConstr->Type = constrType2; - newConstr->First = newGeoId; - newConstr->FirstPos = start; - newConstr->Second = GeoId2; - - if (constrType2 == Sketcher::Coincident) { - newConstr->SecondPos = secondPos2; - delConstraintOnPoint(GeoId2, secondPos2, false); - } - - addConstraint(newConstr); - - newConstr->Type = Sketcher::Coincident; - newConstr->First = GeoId; - newConstr->FirstPos = Sketcher::mid; - newConstr->Second = newGeoId; - newConstr->SecondPos = Sketcher::mid; - addConstraint(newConstr); - - delete newConstr; - - if(noRecomputes) // if we do not have a recompute, the sketch must be solved to update the DoF of the solver - solve(); - - return 0; - } else - return -1; - } else if (theta1 < 0.001*arcLength) { // drop the second intersection point - std::swap(GeoId1,GeoId2); - std::swap(point1,point2); - } else if (theta2 > 0.999*arcLength) { - } - else - return -1; - } - - if (GeoId1 >= 0) { - - ConstraintType constrType = Sketcher::PointOnObject; - PointPos secondPos = Sketcher::none; - for (std::vector::const_iterator it=constraints.begin(); - it != constraints.end(); ++it) { - Constraint *constr = *(it); - if ((constr->First == GeoId1 && constr->Second == GeoId)) { - constrType = Sketcher::Coincident; - secondPos = constr->FirstPos; - delConstraintOnPoint(GeoId1, constr->FirstPos, false); - break; - } - } - - double theta1 = Base::fmod(atan2(point1.y - center.y, point1.x - center.x) - startAngle, 2.f*M_PI) * dir; // x1 - if (theta1 >= 0.001*arcLength && theta1 <= 0.999*arcLength) { - if (theta1 > theta0) { // trim arc start - delConstraintOnPoint(GeoId, start, false); - Part::GeomArcOfCircle *aoc1 = dynamic_cast(geomlist[GeoId]); - aoc1->setRange(startAngle + theta1, endAngle, /*emulateCCW=*/true); - // constrain the trimming point on the corresponding geometry - Sketcher::Constraint *newConstr = new Sketcher::Constraint(); - newConstr->Type = constrType; - newConstr->First = GeoId; - newConstr->FirstPos = start; - newConstr->Second = GeoId1; - - if (constrType == Sketcher::Coincident) - newConstr->SecondPos = secondPos; - - addConstraint(newConstr); - delete newConstr; - - if(noRecomputes) // if we do not have a recompute, the sketch must be solved to update the DoF of the solver - solve(); - - return 0; - } - else { // trim arc end - delConstraintOnPoint(GeoId, end, false); - Part::GeomArcOfCircle *aoc1 = dynamic_cast(geomlist[GeoId]); - aoc1->setRange(startAngle, startAngle + theta1, /*emulateCCW=*/true); - Sketcher::Constraint *newConstr = new Sketcher::Constraint(); - newConstr->Type = constrType; - newConstr->First = GeoId; - newConstr->FirstPos = end; - newConstr->Second = GeoId1; - - if (constrType == Sketcher::Coincident) - newConstr->SecondPos = secondPos; - - addConstraint(newConstr); - delete newConstr; - - if(noRecomputes) // if we do not have a recompute, the sketch must be solved to update the DoF of the solver - solve(); - - return 0; - } - } - } - } else if (geo->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId()) { - const Part::GeomArcOfEllipse *aoe = dynamic_cast(geo); - Base::Vector3d center = aoe->getCenter(); - double startAngle, endAngle; - aoe->getRange(startAngle, endAngle,/*emulateCCW=*/true); - double dir = (startAngle < endAngle) ? 1 : -1; // this is always == 1 - double arcLength = (endAngle - startAngle)*dir; - double theta0 = Base::fmod( - atan2(-aoe->getMajorRadius()*((point.x-center.x)*aoe->getMajorAxisDir().y-(point.y-center.y)*aoe->getMajorAxisDir().x), - aoe->getMinorRadius()*((point.x-center.x)*aoe->getMajorAxisDir().x+(point.y-center.y)*aoe->getMajorAxisDir().y) - )- startAngle, 2.f*M_PI); // x0 - if (GeoId1 >= 0 && GeoId2 >= 0) { - double theta1 = Base::fmod( - atan2(-aoe->getMajorRadius()*((point1.x-center.x)*aoe->getMajorAxisDir().y-(point1.y-center.y)*aoe->getMajorAxisDir().x), - aoe->getMinorRadius()*((point1.x-center.x)*aoe->getMajorAxisDir().x+(point1.y-center.y)*aoe->getMajorAxisDir().y) - )- startAngle, 2.f*M_PI) * dir; // x1 - double theta2 = Base::fmod( - atan2(-aoe->getMajorRadius()*((point2.x-center.x)*aoe->getMajorAxisDir().y-(point2.y-center.y)*aoe->getMajorAxisDir().x), - aoe->getMinorRadius()*((point2.x-center.x)*aoe->getMajorAxisDir().x+(point2.y-center.y)*aoe->getMajorAxisDir().y) - )- startAngle, 2.f*M_PI) * dir; // x2 - - if (theta1 > theta2) { - std::swap(GeoId1,GeoId2); - std::swap(point1,point2); - std::swap(theta1,theta2); - } - if (theta1 >= 0.001*arcLength && theta2 <= 0.999*arcLength) { - // Trim Point between intersection points - if (theta1 < theta0 && theta2 > theta0) { - int newGeoId = addGeometry(geo); - // go through all constraints and replace the point (GeoId,end) with (newGeoId,end) - transferConstraints(GeoId, end, newGeoId, end); - - Part::GeomArcOfEllipse *aoe1 = dynamic_cast(geomlist[GeoId]); - Part::GeomArcOfEllipse *aoe2 = dynamic_cast(geomlist[newGeoId]); - aoe1->setRange(startAngle, startAngle + theta1, /*emulateCCW=*/true); - aoe2->setRange(startAngle + theta2, endAngle, /*emulateCCW=*/true); - - // constrain the trimming points on the corresponding geometries - Sketcher::Constraint *newConstr = new Sketcher::Constraint(); - - // Build Constraints associated with new pair of arcs - newConstr->Type = Sketcher::Equal; - newConstr->First = GeoId; - newConstr->Second = newGeoId; - addConstraint(newConstr); - - PointPos secondPos1 = Sketcher::none, secondPos2 = Sketcher::none; - ConstraintType constrType1 = Sketcher::PointOnObject, constrType2 = Sketcher::PointOnObject; - - for (std::vector::const_iterator it=constraints.begin(); - it != constraints.end(); ++it) { - Constraint *constr = *(it); - if (secondPos1 == Sketcher::none && - (constr->First == GeoId1 && constr->Second == GeoId)) { - constrType1= Sketcher::Coincident; - secondPos1 = constr->FirstPos; - } else if (secondPos2 == Sketcher::none && - (constr->First == GeoId2 && constr->Second == GeoId)) { - constrType2 = Sketcher::Coincident; - secondPos2 = constr->FirstPos; - } - } - - newConstr->Type = constrType1; - newConstr->First = GeoId; - newConstr->FirstPos = end; - newConstr->Second = GeoId1; - - if (constrType1 == Sketcher::Coincident) { - newConstr->SecondPos = secondPos1; - delConstraintOnPoint(GeoId1, secondPos1, false); - } - - addConstraint(newConstr); - - // Reset secondpos in case it was set previously - newConstr->SecondPos = Sketcher::none; - - newConstr->Type = constrType2; - newConstr->First = newGeoId; - newConstr->FirstPos = start; - newConstr->Second = GeoId2; - - if (constrType2 == Sketcher::Coincident) { - newConstr->SecondPos = secondPos2; - delConstraintOnPoint(GeoId2, secondPos2, false); - } - - addConstraint(newConstr); - - newConstr->Type = Sketcher::Coincident; - newConstr->First = GeoId; - newConstr->FirstPos = Sketcher::mid; - newConstr->Second = newGeoId; - newConstr->SecondPos = Sketcher::mid; - addConstraint(newConstr); - - delete newConstr; - - if(noRecomputes) // if we do not have a recompute, the sketch must be solved to update the DoF of the solver - solve(); - - return 0; - } else - return -1; - } else if (theta1 < 0.001*arcLength) { // drop the second intersection point - std::swap(GeoId1,GeoId2); - std::swap(point1,point2); - } else if (theta2 > 0.999*arcLength) { - } else - return -1; - } - - if (GeoId1 >= 0) { - - ConstraintType constrType = Sketcher::PointOnObject; - PointPos secondPos = Sketcher::none; - for (std::vector::const_iterator it=constraints.begin(); - it != constraints.end(); ++it) { - Constraint *constr = *(it); - if ((constr->First == GeoId1 && constr->Second == GeoId)) { - constrType = Sketcher::Coincident; - secondPos = constr->FirstPos; - delConstraintOnPoint(GeoId1, constr->FirstPos, false); - break; - } - } - - double theta1 = Base::fmod( - atan2(-aoe->getMajorRadius()*((point1.x-center.x)*aoe->getMajorAxisDir().y-(point1.y-center.y)*aoe->getMajorAxisDir().x), - aoe->getMinorRadius()*((point1.x-center.x)*aoe->getMajorAxisDir().x+(point1.y-center.y)*aoe->getMajorAxisDir().y) - )- startAngle, 2.f*M_PI) * dir; // x1 - - if (theta1 >= 0.001*arcLength && theta1 <= 0.999*arcLength) { - if (theta1 > theta0) { // trim arc start - delConstraintOnPoint(GeoId, start, false); - Part::GeomArcOfEllipse *aoe1 = dynamic_cast(geomlist[GeoId]); - aoe1->setRange(startAngle + theta1, endAngle, /*emulateCCW=*/true); - // constrain the trimming point on the corresponding geometry - Sketcher::Constraint *newConstr = new Sketcher::Constraint(); - newConstr->Type = constrType; - newConstr->First = GeoId; - newConstr->FirstPos = start; - newConstr->Second = GeoId1; - - if (constrType == Sketcher::Coincident) - newConstr->SecondPos = secondPos; - - addConstraint(newConstr); - delete newConstr; - - if(noRecomputes) // if we do not have a recompute, the sketch must be solved to update the DoF of the solver - solve(); - - return 0; - } - else { // trim arc end - delConstraintOnPoint(GeoId, end, false); - Part::GeomArcOfEllipse *aoe1 = dynamic_cast(geomlist[GeoId]); - aoe1->setRange(startAngle, startAngle + theta1, /*emulateCCW=*/true); - - if(noRecomputes) // if we do not have a recompute, the sketch must be solved to update the DoF of the solver - solve(); - return 0; - } - } - } - } - - return -1; -} - -int SketchObject::addSymmetric(const std::vector &geoIdList, int refGeoId, Sketcher::PointPos refPosId/*=Sketcher::none*/) -{ - const std::vector< Part::Geometry * > &geovals = getInternalGeometry(); - std::vector< Part::Geometry * > newgeoVals(geovals); - - const std::vector< Constraint * > &constrvals = this->Constraints.getValues(); - std::vector< Constraint * > newconstrVals(constrvals); - - int cgeoid = getHighestCurveIndex()+1; - - std::map geoIdMap; - std::map isStartEndInverted; - - // reference is a line - if(refPosId == Sketcher::none) { - const Part::Geometry *georef = getGeometry(refGeoId); - if(georef->getTypeId() != Part::GeomLineSegment::getClassTypeId()) { - Base::Console().Error("Reference for symmetric is neither a point nor a line.\n"); - return -1; - } - - const Part::GeomLineSegment *refGeoLine = static_cast(georef); - //line - Base::Vector3d refstart = refGeoLine->getStartPoint(); - Base::Vector3d vectline = refGeoLine->getEndPoint()-refstart; - - for (std::vector::const_iterator it = geoIdList.begin(); it != geoIdList.end(); ++it) { - const Part::Geometry *geo = getGeometry(*it); - Part::Geometry *geosym = geo->clone(); - - // Handle Geometry - if(geosym->getTypeId() == Part::GeomLineSegment::getClassTypeId()){ - Part::GeomLineSegment *geosymline = static_cast(geosym); - Base::Vector3d sp = geosymline->getStartPoint(); - Base::Vector3d ep = geosymline->getEndPoint(); - - geosymline->setPoints(sp+2.0*(sp.Perpendicular(refGeoLine->getStartPoint(),vectline)-sp), - ep+2.0*(ep.Perpendicular(refGeoLine->getStartPoint(),vectline)-ep)); - isStartEndInverted.insert(std::make_pair(*it, false)); - } - else if(geosym->getTypeId() == Part::GeomCircle::getClassTypeId()){ - Part::GeomCircle *geosymcircle = static_cast(geosym); - Base::Vector3d cp = geosymcircle->getCenter(); - - geosymcircle->setCenter(cp+2.0*(cp.Perpendicular(refGeoLine->getStartPoint(),vectline)-cp)); - isStartEndInverted.insert(std::make_pair(*it, false)); - } - else if(geosym->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()){ - Part::GeomArcOfCircle *geoaoc = static_cast(geosym); - Base::Vector3d sp = geoaoc->getStartPoint(true); - Base::Vector3d ep = geoaoc->getEndPoint(true); - Base::Vector3d cp = geoaoc->getCenter(); - - Base::Vector3d ssp = sp+2.0*(sp.Perpendicular(refGeoLine->getStartPoint(),vectline)-sp); - Base::Vector3d sep = ep+2.0*(ep.Perpendicular(refGeoLine->getStartPoint(),vectline)-ep); - Base::Vector3d scp = cp+2.0*(cp.Perpendicular(refGeoLine->getStartPoint(),vectline)-cp); - - double theta1 = Base::fmod(atan2(sep.y - scp.y, sep.x - scp.x), 2.f*M_PI); - double theta2 = Base::fmod(atan2(ssp.y - scp.y, ssp.x - scp.x), 2.f*M_PI); - - geoaoc->setCenter(scp); - geoaoc->setRange(theta1,theta2,true); - isStartEndInverted.insert(std::make_pair(*it, true)); - } - else if(geosym->getTypeId() == Part::GeomEllipse::getClassTypeId()){ - Part::GeomEllipse *geosymellipse = static_cast(geosym); - Base::Vector3d cp = geosymellipse->getCenter(); - - Base::Vector3d majdir = geosymellipse->getMajorAxisDir(); - double majord=geosymellipse->getMajorRadius(); - double minord=geosymellipse->getMinorRadius(); - double df= sqrt(majord*majord-minord*minord); - Base::Vector3d f1 = cp + df * majdir; - - Base::Vector3d sf1 = f1+2.0*(f1.Perpendicular(refGeoLine->getStartPoint(),vectline)-f1); - Base::Vector3d scp = cp+2.0*(cp.Perpendicular(refGeoLine->getStartPoint(),vectline)-cp); - - geosymellipse->setMajorAxisDir(sf1-scp); - - geosymellipse->setCenter(scp); - isStartEndInverted.insert(std::make_pair(*it, false)); - } - else if(geosym->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId()){ - Part::GeomArcOfEllipse *geosymaoe = static_cast(geosym); - Base::Vector3d cp = geosymaoe->getCenter(); - Base::Vector3d sp = geosymaoe->getStartPoint(true); - Base::Vector3d ep = geosymaoe->getEndPoint(true); - - Base::Vector3d majdir = geosymaoe->getMajorAxisDir(); - double majord=geosymaoe->getMajorRadius(); - double minord=geosymaoe->getMinorRadius(); - double df= sqrt(majord*majord-minord*minord); - Base::Vector3d f1 = cp + df * majdir; - - Base::Vector3d sf1 = f1+2.0*(f1.Perpendicular(refGeoLine->getStartPoint(),vectline)-f1); - Base::Vector3d scp = cp+2.0*(cp.Perpendicular(refGeoLine->getStartPoint(),vectline)-cp); - Base::Vector3d ssp = sp+2.0*(sp.Perpendicular(refGeoLine->getStartPoint(),vectline)-sp); - Base::Vector3d sep = ep+2.0*(ep.Perpendicular(refGeoLine->getStartPoint(),vectline)-ep); - - geosymaoe->setMajorAxisDir(sf1-scp); - - geosymaoe->setCenter(scp); - - double theta1,theta2; - geosymaoe->closestParameter(sep,theta1); - geosymaoe->closestParameter(ssp,theta2); - - geosymaoe->setRange(theta1,theta2,true); - isStartEndInverted.insert(std::make_pair(*it, true)); - } - else if(geosym->getTypeId() == Part::GeomPoint::getClassTypeId()){ - Part::GeomPoint *geosympoint = static_cast(geosym); - Base::Vector3d cp = geosympoint->getPoint(); - - geosympoint->setPoint(cp+2.0*(cp.Perpendicular(refGeoLine->getStartPoint(),vectline)-cp)); - isStartEndInverted.insert(std::make_pair(*it, false)); - } - else { - Base::Console().Error("Unsupported Geometry!! Just copying it.\n"); - isStartEndInverted.insert(std::make_pair(*it, false)); - } - - newgeoVals.push_back(geosym); - geoIdMap.insert(std::make_pair(*it, cgeoid)); - cgeoid++; - } - } - else { //reference is a point - Vector3d refpoint; - const Part::Geometry *georef = getGeometry(refGeoId); - - if (georef->getTypeId() == Part::GeomPoint::getClassTypeId()) { - refpoint = static_cast(georef)->getPoint(); - } - else if ( refGeoId == -1 && refPosId == Sketcher::start) { - refpoint = Vector3d(0,0,0); - } - else { - switch(refPosId){ - case Sketcher::start: - if(georef->getTypeId() == Part::GeomLineSegment::getClassTypeId()){ - const Part::GeomLineSegment *geosymline = static_cast(georef); - refpoint = geosymline->getStartPoint(); - } - else if(georef->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()){ - const Part::GeomArcOfCircle *geoaoc = static_cast(georef); - refpoint = geoaoc->getStartPoint(true); - } - else if(georef->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId()){ - const Part::GeomArcOfEllipse *geosymaoe = static_cast(georef); - refpoint = geosymaoe->getStartPoint(true); - } - break; - case Sketcher::end: - if(georef->getTypeId() == Part::GeomLineSegment::getClassTypeId()){ - const Part::GeomLineSegment *geosymline = static_cast(georef); - refpoint = geosymline->getEndPoint(); - } - else if(georef->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()){ - const Part::GeomArcOfCircle *geoaoc = static_cast(georef); - refpoint = geoaoc->getEndPoint(true); - } - else if(georef->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId()){ - const Part::GeomArcOfEllipse *geosymaoe = static_cast(georef); - refpoint = geosymaoe->getEndPoint(true); - } - break; - case Sketcher::mid: - if(georef->getTypeId() == Part::GeomCircle::getClassTypeId()){ - const Part::GeomCircle *geosymcircle = static_cast(georef); - refpoint = geosymcircle->getCenter(); - } - else if(georef->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()){ - const Part::GeomArcOfCircle *geoaoc = static_cast(georef); - refpoint = geoaoc->getCenter(); - } - else if(georef->getTypeId() == Part::GeomEllipse::getClassTypeId()){ - const Part::GeomEllipse *geosymellipse = static_cast(georef); - refpoint = geosymellipse->getCenter(); - } - else if(georef->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId()){ - const Part::GeomArcOfEllipse *geosymaoe = static_cast(georef); - refpoint = geosymaoe->getCenter(); - } - break; - default: - Base::Console().Error("Wrong PointPosId.\n"); - return -1; - } - } - - for (std::vector::const_iterator it = geoIdList.begin(); it != geoIdList.end(); ++it) { - const Part::Geometry *geo = getGeometry(*it); - Part::Geometry *geosym = geo->clone(); - - // Handle Geometry - if(geosym->getTypeId() == Part::GeomLineSegment::getClassTypeId()){ - Part::GeomLineSegment *geosymline = static_cast(geosym); - Base::Vector3d sp = geosymline->getStartPoint(); - Base::Vector3d ep = geosymline->getEndPoint(); - Base::Vector3d ssp = sp + 2.0*(refpoint-sp); - Base::Vector3d sep = ep + 2.0*(refpoint-ep); - - geosymline->setPoints(ssp, sep); - isStartEndInverted.insert(std::make_pair(*it, false)); - } - else if(geosym->getTypeId() == Part::GeomCircle::getClassTypeId()){ - Part::GeomCircle *geosymcircle = static_cast(geosym); - Base::Vector3d cp = geosymcircle->getCenter(); - - geosymcircle->setCenter(cp + 2.0*(refpoint-cp)); - isStartEndInverted.insert(std::make_pair(*it, false)); - } - else if(geosym->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()){ - Part::GeomArcOfCircle *geoaoc = static_cast(geosym); - Base::Vector3d sp = geoaoc->getStartPoint(true); - Base::Vector3d ep = geoaoc->getEndPoint(true); - Base::Vector3d cp = geoaoc->getCenter(); - - Base::Vector3d ssp = sp + 2.0*(refpoint-sp); - Base::Vector3d sep = ep + 2.0*(refpoint-ep); - Base::Vector3d scp = cp + 2.0*(refpoint-cp); - - double theta1 = Base::fmod(atan2(ssp.y - scp.y, ssp.x - scp.x), 2.f*M_PI); - double theta2 = Base::fmod(atan2(sep.y - scp.y, sep.x - scp.x), 2.f*M_PI); - - geoaoc->setCenter(scp); - geoaoc->setRange(theta1,theta2,true); - isStartEndInverted.insert(std::make_pair(*it, false)); - } - else if(geosym->getTypeId() == Part::GeomEllipse::getClassTypeId()){ - Part::GeomEllipse *geosymellipse = static_cast(geosym); - Base::Vector3d cp = geosymellipse->getCenter(); - - Base::Vector3d majdir = geosymellipse->getMajorAxisDir(); - double majord=geosymellipse->getMajorRadius(); - double minord=geosymellipse->getMinorRadius(); - double df= sqrt(majord*majord-minord*minord); - Base::Vector3d f1 = cp + df * majdir; - - Base::Vector3d sf1 = f1 + 2.0*(refpoint-f1); - Base::Vector3d scp = cp + 2.0*(refpoint-cp); - - geosymellipse->setMajorAxisDir(sf1-scp); - - geosymellipse->setCenter(scp); - isStartEndInverted.insert(std::make_pair(*it, false)); - } - else if(geosym->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId()){ - Part::GeomArcOfEllipse *geosymaoe = static_cast(geosym); - Base::Vector3d cp = geosymaoe->getCenter(); - Base::Vector3d sp = geosymaoe->getStartPoint(true); - Base::Vector3d ep = geosymaoe->getEndPoint(true); - - Base::Vector3d majdir = geosymaoe->getMajorAxisDir(); - double majord=geosymaoe->getMajorRadius(); - double minord=geosymaoe->getMinorRadius(); - double df= sqrt(majord*majord-minord*minord); - Base::Vector3d f1 = cp + df * majdir; - - Base::Vector3d sf1 = f1 + 2.0*(refpoint-f1); - Base::Vector3d scp = cp + 2.0*(refpoint-cp); - Base::Vector3d ssp = sp + 2.0*(refpoint-sp); - Base::Vector3d sep = ep + 2.0*(refpoint-ep); - - geosymaoe->setMajorAxisDir(sf1-scp); - - geosymaoe->setCenter(scp); - - double theta1,theta2; - geosymaoe->closestParameter(ssp,theta1); - geosymaoe->closestParameter(sep,theta2); - - geosymaoe->setRange(theta1,theta2,true); - isStartEndInverted.insert(std::make_pair(*it, false)); - } - else if(geosym->getTypeId() == Part::GeomPoint::getClassTypeId()){ - Part::GeomPoint *geosympoint = static_cast(geosym); - Base::Vector3d cp = geosympoint->getPoint(); - - geosympoint->setPoint(cp + 2.0*(refpoint-cp)); - isStartEndInverted.insert(std::make_pair(*it, false)); - } - else { - Base::Console().Error("Unsupported Geometry!! Just copying it.\n"); - isStartEndInverted.insert(std::make_pair(*it, false)); - } - - newgeoVals.push_back(geosym); - geoIdMap.insert(std::make_pair(*it, cgeoid)); - cgeoid++; - } - } - - // add the geometry - Geometry.setValues(newgeoVals); - Constraints.acceptGeometry(getCompleteGeometry()); - rebuildVertexIndex(); - - for (std::vector::const_iterator it = constrvals.begin(); it != constrvals.end(); ++it) { - - std::vector::const_iterator fit=std::find(geoIdList.begin(), geoIdList.end(), (*it)->First); - - if(fit != geoIdList.end()) { // if First of constraint is in geoIdList - - if( (*it)->Second == Constraint::GeoUndef /*&& (*it)->Third == Constraint::GeoUndef*/) { - if( (*it)->Type != Sketcher::DistanceX && - (*it)->Type != Sketcher::DistanceY) { - - Constraint *constNew = (*it)->copy(); - - constNew->First = geoIdMap[(*it)->First]; - newconstrVals.push_back(constNew); - } - } - else { // other geoids intervene in this constraint - - std::vector::const_iterator sit=std::find(geoIdList.begin(), geoIdList.end(), (*it)->Second); - - if(sit != geoIdList.end()) { // Second is also in the list - - if( (*it)->Third == Constraint::GeoUndef ) { - if((*it)->Type == Sketcher::Coincident || - (*it)->Type == Sketcher::Perpendicular || - (*it)->Type == Sketcher::Parallel || - (*it)->Type == Sketcher::Tangent || - (*it)->Type == Sketcher::Distance || - (*it)->Type == Sketcher::Equal || - (*it)->Type == Sketcher::Radius || - (*it)->Type == Sketcher::PointOnObject ){ - Constraint *constNew = (*it)->copy(); - - constNew->First = geoIdMap[(*it)->First]; - constNew->Second = geoIdMap[(*it)->Second]; - if(isStartEndInverted[(*it)->First]){ - if((*it)->FirstPos == Sketcher::start) - constNew->FirstPos = Sketcher::end; - else if((*it)->FirstPos == Sketcher::end) - constNew->FirstPos = Sketcher::start; - } - if(isStartEndInverted[(*it)->Second]){ - if((*it)->SecondPos == Sketcher::start) - constNew->SecondPos = Sketcher::end; - else if((*it)->SecondPos == Sketcher::end) - constNew->SecondPos = Sketcher::start; - } - - if (constNew->Type == Tangent || constNew->Type == Perpendicular) - AutoLockTangencyAndPerpty(constNew,true); - - newconstrVals.push_back(constNew); - } - } - else { - std::vector::const_iterator tit=std::find(geoIdList.begin(), geoIdList.end(), (*it)->Third); - - if(tit != geoIdList.end()) { // Third is also in the list - Constraint *constNew = (*it)->copy(); - constNew->First = geoIdMap[(*it)->First]; - constNew->Second = geoIdMap[(*it)->Second]; - constNew->Third = geoIdMap[(*it)->Third]; - if(isStartEndInverted[(*it)->First]){ - if((*it)->FirstPos == Sketcher::start) - constNew->FirstPos = Sketcher::end; - else if((*it)->FirstPos == Sketcher::end) - constNew->FirstPos = Sketcher::start; - } - if(isStartEndInverted[(*it)->Second]){ - if((*it)->SecondPos == Sketcher::start) - constNew->SecondPos = Sketcher::end; - else if((*it)->SecondPos == Sketcher::end) - constNew->SecondPos = Sketcher::start; - } - if(isStartEndInverted[(*it)->Third]){ - if((*it)->ThirdPos == Sketcher::start) - constNew->ThirdPos = Sketcher::end; - else if((*it)->ThirdPos == Sketcher::end) - constNew->ThirdPos = Sketcher::start; - } - newconstrVals.push_back(constNew); - } - } - } - } - } - } - - if( newconstrVals.size() > constrvals.size() ) - Constraints.setValues(newconstrVals); - - return Geometry.getSize()-1; -} - -int SketchObject::addCopy(const std::vector &geoIdList, const Base::Vector3d& displacement, bool clone /*=false*/, int csize/*=2*/, int rsize/*=1*/, - bool constraindisplacement /*= false*/, double perpscale /*= 1.0*/) -{ - const std::vector< Part::Geometry * > &geovals = getInternalGeometry(); - std::vector< Part::Geometry * > newgeoVals(geovals); - - const std::vector< Constraint * > &constrvals = this->Constraints.getValues(); - std::vector< Constraint * > newconstrVals(constrvals); - - int cgeoid = getHighestCurveIndex()+1; - - int iterfirstgeoid = -1 ; - - Base::Vector3d iterfirstpoint; - - int refgeoid = -1; - - int colrefgeoid = 0, rowrefgeoid = 0; - - int currentrowfirstgeoid= -1, prevrowstartfirstgeoid = -1, prevfirstgeoid = -1; - - Sketcher::PointPos refposId = Sketcher::none; - - std::map geoIdMap; - - Base::Vector3d perpendicularDisplacement = Base::Vector3d(perpscale*displacement.y,perpscale*-displacement.x,0); - - int x,y; - - for (y=0;ygetTypeId() == Part::GeomCircle::getClassTypeId() || - geo->getTypeId() == Part::GeomEllipse::getClassTypeId() ){ - refposId = Sketcher::mid; - } - else - refposId = Sketcher::start; - - continue; // the first element is already in place - } - else { - prevfirstgeoid = iterfirstgeoid; - - iterfirstgeoid = cgeoid; - - if( x == 0 ) { // if first element of second row - prevrowstartfirstgeoid = currentrowfirstgeoid; - currentrowfirstgeoid = cgeoid; - } - } - - for (std::vector::const_iterator it = geoIdList.begin(); it != geoIdList.end(); ++it) { - const Part::Geometry *geo = getGeometry(*it); - Part::Geometry *geocopy = geo->clone(); - - // Handle Geometry - if(geocopy->getTypeId() == Part::GeomLineSegment::getClassTypeId()){ - Part::GeomLineSegment *geosymline = static_cast(geocopy); - Base::Vector3d ep = geosymline->getEndPoint(); - Base::Vector3d ssp = geosymline->getStartPoint()+double(x)*displacement+double(y)*perpendicularDisplacement; - - geosymline->setPoints( ssp, - ep+double(x)*displacement+double(y)*perpendicularDisplacement); - - if(it == geoIdList.begin()) - iterfirstpoint = ssp; - } - else if(geocopy->getTypeId() == Part::GeomCircle::getClassTypeId()){ - Part::GeomCircle *geosymcircle = static_cast(geocopy); - Base::Vector3d cp = geosymcircle->getCenter(); - Base::Vector3d scp = cp+double(x)*displacement+double(y)*perpendicularDisplacement; - - geosymcircle->setCenter(scp); - - if(it == geoIdList.begin()) - iterfirstpoint = scp; - } - else if(geocopy->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()){ - Part::GeomArcOfCircle *geoaoc = static_cast(geocopy); - Base::Vector3d cp = geoaoc->getCenter(); - Base::Vector3d scp = cp+double(x)*displacement+double(y)*perpendicularDisplacement; - - geoaoc->setCenter(scp); - - if(it == geoIdList.begin()) - iterfirstpoint = geoaoc->getStartPoint(true); - } - else if(geocopy->getTypeId() == Part::GeomEllipse::getClassTypeId()){ - Part::GeomEllipse *geosymellipse = static_cast(geocopy); - Base::Vector3d cp = geosymellipse->getCenter(); - Base::Vector3d scp = cp+double(x)*displacement+double(y)*perpendicularDisplacement; - - geosymellipse->setCenter(scp); - - if(it == geoIdList.begin()) - iterfirstpoint = scp; - } - else if(geocopy->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId()){ - Part::GeomArcOfEllipse *geoaoe = static_cast(geocopy); - Base::Vector3d cp = geoaoe->getCenter(); - Base::Vector3d scp = cp+double(x)*displacement+double(y)*perpendicularDisplacement; - - geoaoe->setCenter(scp); - - if(it == geoIdList.begin()) - iterfirstpoint = geoaoe->getStartPoint(true); - } - else if(geocopy->getTypeId() == Part::GeomPoint::getClassTypeId()){ - Part::GeomPoint *geopoint = static_cast(geocopy); - Base::Vector3d cp = geopoint->getPoint(); - Base::Vector3d scp = cp+double(x)*displacement+double(y)*perpendicularDisplacement; - geopoint->setPoint(scp); - - if(it == geoIdList.begin()) - iterfirstpoint = scp; - } - else { - Base::Console().Error("Unsupported Geometry!! Just skipping it.\n"); - continue; - } - - newgeoVals.push_back(geocopy); - geoIdMap.insert(std::make_pair(*it, cgeoid)); - cgeoid++; - } - - // handle geometry constraints - for (std::vector::const_iterator it = constrvals.begin(); it != constrvals.end(); ++it) { - - std::vector::const_iterator fit=std::find(geoIdList.begin(), geoIdList.end(), (*it)->First); - - if(fit != geoIdList.end()) { // if First of constraint is in geoIdList - - if( (*it)->Second == Constraint::GeoUndef /*&& (*it)->Third == Constraint::GeoUndef*/) { - if( ((*it)->Type != Sketcher::DistanceX && (*it)->Type != Sketcher::DistanceY ) || - (*it)->FirstPos == Sketcher::none ) { // if it is not a point locking DistanceX/Y - if (((*it)->Type == Sketcher::DistanceX || - (*it)->Type == Sketcher::DistanceY || - (*it)->Type == Sketcher::Distance || - (*it)->Type == Sketcher::Radius ) && clone ) { - // Distances on a single Element are mapped to equality constraints in clone mode - Constraint *constNew = (*it)->copy(); - constNew->Type = Sketcher::Equal; - constNew->Second = geoIdMap[(*it)->First]; // first is already (*it->First) - newconstrVals.push_back(constNew); - } - else if ((*it)->Type == Sketcher::Angle && clone){ - // Angles on a single Element are mapped to parallel constraints in clone mode - Constraint *constNew = (*it)->copy(); - constNew->Type = Sketcher::Parallel; - constNew->Second = geoIdMap[(*it)->First]; // first is already (*it->First) - newconstrVals.push_back(constNew); - } - else { - Constraint *constNew = (*it)->copy(); - constNew->First = geoIdMap[(*it)->First]; - newconstrVals.push_back(constNew); - } - } - } - else { // other geoids intervene in this constraint - - std::vector::const_iterator sit=std::find(geoIdList.begin(), geoIdList.end(), (*it)->Second); - - if(sit != geoIdList.end()) { // Second is also in the list - if( (*it)->Third == Constraint::GeoUndef ) { - if (((*it)->Type == Sketcher::DistanceX || - (*it)->Type == Sketcher::DistanceY || - (*it)->Type == Sketcher::Distance) && ((*it)->First == (*it)->Second) && clone ) { - // Distances on a two Elements, which must be points of the same line are mapped to equality constraints in clone mode - Constraint *constNew = (*it)->copy(); - constNew->Type = Sketcher::Equal; - constNew->FirstPos = Sketcher::none; - constNew->Second = geoIdMap[(*it)->First]; // first is already (*it->First) - constNew->SecondPos = Sketcher::none; - newconstrVals.push_back(constNew); - } - else { - Constraint *constNew = (*it)->copy(); - constNew->First = geoIdMap[(*it)->First]; - constNew->Second = geoIdMap[(*it)->Second]; - newconstrVals.push_back(constNew); - } - } - else { - std::vector::const_iterator tit=std::find(geoIdList.begin(), geoIdList.end(), (*it)->Third); - - if(tit != geoIdList.end()) { // Third is also in the list - Constraint *constNew = (*it)->copy(); - constNew->First = geoIdMap[(*it)->First]; - constNew->Second = geoIdMap[(*it)->Second]; - constNew->Third = geoIdMap[(*it)->Third]; - - newconstrVals.push_back(constNew); - } - } - } - } - } - } - - // handle inter-geometry constraints - if(constraindisplacement){ - - // add a construction line - Part::GeomLineSegment *constrline= new Part::GeomLineSegment(); - - Base::Vector3d sp = getPoint(refgeoid,refposId)+ ( ( x == 0 )? - (double(x)*displacement+double(y-1)*perpendicularDisplacement): - (double(x-1)*displacement+double(y)*perpendicularDisplacement)); // position of the reference point - Base::Vector3d ep = iterfirstpoint; // position of the current instance corresponding point - constrline->setPoints(sp,ep); - constrline->Construction=true; - - newgeoVals.push_back(constrline); - - Constraint *constNew; - - if(x == 0) { // first element of a row - - // add coincidents for construction line - constNew = new Constraint(); - constNew->Type = Sketcher::Coincident; - constNew->First = prevrowstartfirstgeoid; - constNew->FirstPos = refposId; - constNew->Second = cgeoid; - constNew->SecondPos = Sketcher::start; - newconstrVals.push_back(constNew); - - constNew = new Constraint(); - constNew->Type = Sketcher::Coincident; - constNew->First = iterfirstgeoid; - constNew->FirstPos = refposId; - constNew->Second = cgeoid; - constNew->SecondPos = Sketcher::end; - newconstrVals.push_back(constNew); - - if( y == 1 ) { // it is the first added element of this row in the perpendicular to displacementvector direction - rowrefgeoid = cgeoid; - cgeoid++; - - // add length (or equal if perpscale==1) and perpendicular - if(perpscale==1.0) { - constNew = new Constraint(); - constNew->Type = Sketcher::Equal; - constNew->First = rowrefgeoid; - constNew->FirstPos = Sketcher::none; - constNew->Second = colrefgeoid; - constNew->SecondPos = Sketcher::none; - newconstrVals.push_back(constNew); - } else { - constNew = new Constraint(); - constNew->Type = Sketcher::Distance; - constNew->First = rowrefgeoid; - constNew->FirstPos = Sketcher::none; - constNew->setValue(perpendicularDisplacement.Length()); - newconstrVals.push_back(constNew); - } - - constNew = new Constraint(); - constNew->Type = Sketcher::Perpendicular; - constNew->First = rowrefgeoid; - constNew->FirstPos = Sketcher::none; - constNew->Second = colrefgeoid; - constNew->SecondPos = Sketcher::none; - newconstrVals.push_back(constNew); - } - else { // it is just one more element in the col direction - cgeoid++; - - // all other first rowers get an equality and perpendicular constraint - constNew = new Constraint(); - constNew->Type = Sketcher::Equal; - constNew->First = rowrefgeoid; - constNew->FirstPos = Sketcher::none; - constNew->Second = cgeoid-1; - constNew->SecondPos = Sketcher::none; - newconstrVals.push_back(constNew); - - constNew = new Constraint(); - constNew->Type = Sketcher::Perpendicular; - constNew->First = cgeoid-1; - constNew->FirstPos = Sketcher::none; - constNew->Second = colrefgeoid; - constNew->SecondPos = Sketcher::none; - newconstrVals.push_back(constNew); - } - } - else { // any element not being the first element of a row - - // add coincidents for construction line - constNew = new Constraint(); - constNew->Type = Sketcher::Coincident; - constNew->First = prevfirstgeoid; - constNew->FirstPos = refposId; - constNew->Second = cgeoid; - constNew->SecondPos = Sketcher::start; - newconstrVals.push_back(constNew); - - constNew = new Constraint(); - constNew->Type = Sketcher::Coincident; - constNew->First = iterfirstgeoid; - constNew->FirstPos = refposId; - constNew->Second = cgeoid; - constNew->SecondPos = Sketcher::end; - newconstrVals.push_back(constNew); - - if(y == 0 && x == 1) { // first element of the first row - colrefgeoid = cgeoid; - cgeoid++; - - // add length and Angle - constNew = new Constraint(); - constNew->Type = Sketcher::Distance; - constNew->First = colrefgeoid; - constNew->FirstPos = Sketcher::none; - constNew->setValue(displacement.Length()); - newconstrVals.push_back(constNew); - - constNew = new Constraint(); - constNew->Type = Sketcher::Angle; - constNew->First = colrefgeoid; - constNew->FirstPos = Sketcher::none; - constNew->setValue(atan2(displacement.y,displacement.x)); - newconstrVals.push_back(constNew); - } - else { // any other element - cgeoid++; - - // all other elements get an equality and parallel constraint - constNew = new Constraint(); - constNew->Type = Sketcher::Equal; - constNew->First = colrefgeoid; - constNew->FirstPos = Sketcher::none; - constNew->Second = cgeoid-1; - constNew->SecondPos = Sketcher::none; - newconstrVals.push_back(constNew); - - constNew = new Constraint(); - constNew->Type = Sketcher::Parallel; - constNew->First = cgeoid-1; - constNew->FirstPos = Sketcher::none; - constNew->Second = colrefgeoid; - constNew->SecondPos = Sketcher::none; - newconstrVals.push_back(constNew); - } - } - } - - geoIdMap.clear(); // after each creation reset map so that the key-value is univoque - } - } - - Geometry.setValues(newgeoVals); - Constraints.acceptGeometry(getCompleteGeometry()); - rebuildVertexIndex(); - - if( newconstrVals.size() > constrvals.size() ) - Constraints.setValues(newconstrVals); - - return Geometry.getSize()-1; - -} - -int SketchObject::ExposeInternalGeometry(int GeoId) -{ - if (GeoId < 0 || GeoId > getHighestCurveIndex()) - return -1; - - const Part::Geometry *geo = getGeometry(GeoId); - // Only for supported types - if(geo->getTypeId() == Part::GeomEllipse::getClassTypeId() || geo->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId()) { - // First we search what has to be restored - bool major=false; - bool minor=false; - bool focus1=false; - bool focus2=false; - - const std::vector< Sketcher::Constraint * > &vals = Constraints.getValues(); - - for (std::vector< Sketcher::Constraint * >::const_iterator it= vals.begin(); - it != vals.end(); ++it) { - if((*it)->Type == Sketcher::InternalAlignment && (*it)->Second == GeoId) - { - switch((*it)->AlignmentType){ - case Sketcher::EllipseMajorDiameter: - major=true; - break; - case Sketcher::EllipseMinorDiameter: - minor=true; - break; - case Sketcher::EllipseFocus1: - focus1=true; - break; - case Sketcher::EllipseFocus2: - focus2=true; - break; - default: - return -1; - } - } - } - - int currentgeoid= getHighestCurveIndex(); - int incrgeo= 0; - - Base::Vector3d center; - double majord; - double minord; - Base::Vector3d majdir; - - std::vector igeo; - std::vector icon; - - if(geo->getTypeId() == Part::GeomEllipse::getClassTypeId()){ - const Part::GeomEllipse *ellipse = static_cast(geo); - - center=ellipse->getCenter(); - majord=ellipse->getMajorRadius(); - minord=ellipse->getMinorRadius(); - majdir=ellipse->getMajorAxisDir(); - } - else { - const Part::GeomArcOfEllipse *aoe = static_cast(geo); - - center=aoe->getCenter(); - majord=aoe->getMajorRadius(); - minord=aoe->getMinorRadius(); - majdir=aoe->getMajorAxisDir(); - } - - Base::Vector3d mindir = Vector3d(-majdir.y, majdir.x); - - Base::Vector3d majorpositiveend = center + majord * majdir; - Base::Vector3d majornegativeend = center - majord * majdir; - Base::Vector3d minorpositiveend = center + minord * mindir; - Base::Vector3d minornegativeend = center - minord * mindir; - - double df= sqrt(majord*majord-minord*minord); - - Base::Vector3d focus1P = center + df * majdir; - Base::Vector3d focus2P = center - df * majdir; - - if(!major) - { - Part::GeomLineSegment *lmajor = new Part::GeomLineSegment(); - lmajor->setPoints(majorpositiveend,majornegativeend); - - igeo.push_back(lmajor); - - Sketcher::Constraint *newConstr = new Sketcher::Constraint(); - newConstr->Type = Sketcher::InternalAlignment; - newConstr->AlignmentType = EllipseMajorDiameter; - newConstr->First = currentgeoid+incrgeo+1; - newConstr->Second = GeoId; - - icon.push_back(newConstr); - incrgeo++; - } - if(!minor) - { - Part::GeomLineSegment *lminor = new Part::GeomLineSegment(); - lminor->setPoints(minorpositiveend,minornegativeend); - - igeo.push_back(lminor); - - Sketcher::Constraint *newConstr = new Sketcher::Constraint(); - newConstr->Type = Sketcher::InternalAlignment; - newConstr->AlignmentType = EllipseMinorDiameter; - newConstr->First = currentgeoid+incrgeo+1; - newConstr->Second = GeoId; - - icon.push_back(newConstr); - incrgeo++; - } - if(!focus1) - { - Part::GeomPoint *pf1 = new Part::GeomPoint(); - pf1->setPoint(focus1P); - - igeo.push_back(pf1); - - Sketcher::Constraint *newConstr = new Sketcher::Constraint(); - newConstr->Type = Sketcher::InternalAlignment; - newConstr->AlignmentType = EllipseFocus1; - newConstr->First = currentgeoid+incrgeo+1; - newConstr->FirstPos = Sketcher::start; - newConstr->Second = GeoId; - - icon.push_back(newConstr); - incrgeo++; - } - if(!focus2) - { - Part::GeomPoint *pf2 = new Part::GeomPoint(); - pf2->setPoint(focus2P); - igeo.push_back(pf2); - - Sketcher::Constraint *newConstr = new Sketcher::Constraint(); - newConstr->Type = Sketcher::InternalAlignment; - newConstr->AlignmentType = EllipseFocus2; - newConstr->First = currentgeoid+incrgeo+1; - newConstr->FirstPos = Sketcher::start; - newConstr->Second = GeoId; - - icon.push_back(newConstr); - } - - this->addGeometry(igeo,true); - this->addConstraints(icon); - - for (std::vector::iterator it=igeo.begin(); it != igeo.end(); ++it) - if (*it) - delete *it; - - for (std::vector::iterator it=icon.begin(); it != icon.end(); ++it) - if (*it) - delete *it; - - icon.clear(); - igeo.clear(); - - return incrgeo; //number of added elements - } - else - return -1; // not supported type -} - -int SketchObject::DeleteUnusedInternalGeometry(int GeoId) -{ - if (GeoId < 0 || GeoId > getHighestCurveIndex()) - return -1; - - const Part::Geometry *geo = getGeometry(GeoId); - // Only for supported types - if(geo->getTypeId() == Part::GeomEllipse::getClassTypeId() || geo->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId()) { - - int majorelementindex=-1; - int minorelementindex=-1; - int focus1elementindex=-1; - int focus2elementindex=-1; - - const std::vector< Sketcher::Constraint * > &vals = Constraints.getValues(); - - for (std::vector< Sketcher::Constraint * >::const_iterator it= vals.begin(); - it != vals.end(); ++it) { - if((*it)->Type == Sketcher::InternalAlignment && (*it)->Second == GeoId) - { - switch((*it)->AlignmentType){ - case Sketcher::EllipseMajorDiameter: - majorelementindex=(*it)->First; - break; - case Sketcher::EllipseMinorDiameter: - minorelementindex=(*it)->First; - break; - case Sketcher::EllipseFocus1: - focus1elementindex=(*it)->First; - break; - case Sketcher::EllipseFocus2: - focus2elementindex=(*it)->First; - break; - default: - return -1; - } - } - } - - // Hide unused geometry here - int majorconstraints=0; // number of constraints associated to the geoid of the major axis - int minorconstraints=0; - int focus1constraints=0; - int focus2constraints=0; - - for (std::vector< Sketcher::Constraint * >::const_iterator it= vals.begin(); - it != vals.end(); ++it) { - - if((*it)->Second == majorelementindex || (*it)->First == majorelementindex || (*it)->Third == majorelementindex) - majorconstraints++; - else if((*it)->Second == minorelementindex || (*it)->First == minorelementindex || (*it)->Third == minorelementindex) - minorconstraints++; - else if((*it)->Second == focus1elementindex || (*it)->First == focus1elementindex || (*it)->Third == focus1elementindex) - focus1constraints++; - else if((*it)->Second == focus2elementindex || (*it)->First == focus2elementindex || (*it)->Third == focus2elementindex) - focus2constraints++; - } - - std::vector delgeometries; - - // those with less than 2 constraints must be removed - if(focus2constraints<2) - delgeometries.push_back(focus2elementindex); - - if(focus1constraints<2) - delgeometries.push_back(focus1elementindex); - - if(minorconstraints<2) - delgeometries.push_back(minorelementindex); - - if(majorconstraints<2) - delgeometries.push_back(majorelementindex); - - std::sort(delgeometries.begin(), delgeometries.end()); // indices over an erased element get automatically updated!! - - if(delgeometries.size()>0) - { - for (std::vector::reverse_iterator it=delgeometries.rbegin(); it!=delgeometries.rend(); ++it) { - delGeometry(*it); - } - } - - return delgeometries.size(); //number of deleted elements - } - else - return -1; // not supported type -} - -int SketchObject::addExternal(App::DocumentObject *Obj, const char* SubName) -{ - // so far only externals to the support of the sketch and datum features - if (Support.getValue() != Obj) - if (!Obj->getTypeId().isDerivedFrom(App::Plane::getClassTypeId()) && - !Obj->getTypeId().isDerivedFrom(Part::Datum::getClassTypeId())) - return -1; - - // get the actual lists of the externals - std::vector Objects = ExternalGeometry.getValues(); - std::vector SubElements = ExternalGeometry.getSubValues(); - - const std::vector originalObjects = Objects; - const std::vector originalSubElements = SubElements; - - std::vector::iterator it; - it = std::find(SubElements.begin(), SubElements.end(), SubName); - - // avoid duplicates - if (it != SubElements.end()) - return -1; - - // add the new ones - Objects.push_back(Obj); - SubElements.push_back(std::string(SubName)); - - // set the Link list. - ExternalGeometry.setValues(Objects,SubElements); - try { - rebuildExternalGeometry(); - } - catch (const Base::Exception& e) { - Base::Console().Error("%s\n", e.what()); - // revert to original values - ExternalGeometry.setValues(originalObjects,originalSubElements); - return -1; - } - - solverNeedsUpdate=true; - Constraints.acceptGeometry(getCompleteGeometry()); - rebuildVertexIndex(); - return ExternalGeometry.getValues().size()-1; -} - -int SketchObject::delExternal(int ExtGeoId) -{ - // get the actual lists of the externals - std::vector Objects = ExternalGeometry.getValues(); - std::vector SubElements = ExternalGeometry.getSubValues(); - - if (ExtGeoId < 0 || ExtGeoId >= int(SubElements.size())) - return -1; - - const std::vector originalObjects = Objects; - const std::vector originalSubElements = SubElements; - - Objects.erase(Objects.begin()+ExtGeoId); - SubElements.erase(SubElements.begin()+ExtGeoId); - - const std::vector< Constraint * > &constraints = Constraints.getValues(); - std::vector< Constraint * > newConstraints(0); - int GeoId = -3 - ExtGeoId; - for (std::vector::const_iterator it = constraints.begin(); - it != constraints.end(); ++it) { - if ((*it)->First != GeoId && (*it)->Second != GeoId && (*it)->Third != GeoId) { - Constraint *copiedConstr = (*it)->clone(); - if (copiedConstr->First < GeoId && - copiedConstr->First != Constraint::GeoUndef) - copiedConstr->First += 1; - if (copiedConstr->Second < GeoId && - copiedConstr->Second != Constraint::GeoUndef) - copiedConstr->Second += 1; - if (copiedConstr->Third < GeoId && - copiedConstr->Third != Constraint::GeoUndef) - copiedConstr->Third += 1; - - newConstraints.push_back(copiedConstr); - } - } - - ExternalGeometry.setValues(Objects,SubElements); - try { - rebuildExternalGeometry(); - } - catch (const Base::Exception& e) { - Base::Console().Error("%s\n", e.what()); - // revert to original values - ExternalGeometry.setValues(originalObjects,originalSubElements); - return -1; - } - - solverNeedsUpdate=true; - Constraints.setValues(newConstraints); - Constraints.acceptGeometry(getCompleteGeometry()); - rebuildVertexIndex(); - return 0; -} - -int SketchObject::delAllExternal() -{ - // get the actual lists of the externals - std::vector Objects = ExternalGeometry.getValues(); - std::vector SubElements = ExternalGeometry.getSubValues(); - - const std::vector originalObjects = Objects; - const std::vector originalSubElements = SubElements; - - Objects.clear(); - - SubElements.clear(); - - const std::vector< Constraint * > &constraints = Constraints.getValues(); - std::vector< Constraint * > newConstraints(0); - - for (std::vector::const_iterator it = constraints.begin(); it != constraints.end(); ++it) { - if ((*it)->First > -3 && - ((*it)->Second > -3 || (*it)->Second == Constraint::GeoUndef ) && - ((*it)->Third > -3 || (*it)->Third == Constraint::GeoUndef) ) { - Constraint *copiedConstr = (*it)->clone(); - - newConstraints.push_back(copiedConstr); - } - } - - ExternalGeometry.setValues(Objects,SubElements); - try { - rebuildExternalGeometry(); - } - catch (const Base::Exception& e) { - Base::Console().Error("%s\n", e.what()); - // revert to original values - ExternalGeometry.setValues(originalObjects,originalSubElements); - return -1; - } - - solverNeedsUpdate=true; - Constraints.setValues(newConstraints); - Constraints.acceptGeometry(getCompleteGeometry()); - rebuildVertexIndex(); - return 0; -} - -int SketchObject::delConstraintsToExternal() -{ - const std::vector< Constraint * > &constraints = Constraints.getValuesForce(); - std::vector< Constraint * > newConstraints(0); - int GeoId = -3, NullId = -2000; - for (std::vector::const_iterator it = constraints.begin(); - it != constraints.end(); ++it) { - if ( (*it)->First > GeoId - && - ((*it)->Second > GeoId || (*it)->Second == NullId) - && - ((*it)->Third > GeoId || (*it)->Third == NullId)) { - newConstraints.push_back(*it); - } - } - - Constraints.setValues(newConstraints); - Constraints.acceptGeometry(getCompleteGeometry()); - - if(noRecomputes) // if we do not have a recompute, the sketch must be solved to update the DoF of the solver - solve(); - - return 0; -} - -const Part::Geometry* SketchObject::getGeometry(int GeoId) const -{ - if (GeoId >= 0) { - const std::vector &geomlist = getInternalGeometry(); - if (GeoId < int(geomlist.size())) - return geomlist[GeoId]; - } - else if (GeoId <= -1 && -GeoId <= int(ExternalGeo.size())) - return ExternalGeo[-GeoId-1]; - - return 0; -} - -// Auxiliary method -Part::Geometry* projectLine(const BRepAdaptor_Curve& curve, const Handle(Geom_Plane)& gPlane, const Base::Placement& invPlm) -{ - double first = curve.FirstParameter(); - bool infinite = false; - if (fabs(first) > 1E99) { - // TODO: What is OCE's definition of Infinite? - // TODO: The clean way to do this is to handle a new sketch geometry Geom::Line - // but its a lot of work to implement... - first = -10000; - //infinite = true; - } - double last = curve.LastParameter(); - if (fabs(last) > 1E99) { - last = +10000; - //infinite = true; - } - - gp_Pnt P1 = curve.Value(first); - gp_Pnt P2 = curve.Value(last); - - GeomAPI_ProjectPointOnSurf proj1(P1,gPlane); - P1 = proj1.NearestPoint(); - GeomAPI_ProjectPointOnSurf proj2(P2,gPlane); - P2 = proj2.NearestPoint(); - - Base::Vector3d p1(P1.X(),P1.Y(),P1.Z()); - Base::Vector3d p2(P2.X(),P2.Y(),P2.Z()); - invPlm.multVec(p1,p1); - invPlm.multVec(p2,p2); - - if (Base::Distance(p1,p2) < Precision::Confusion()) { - Base::Vector3d p = (p1 + p2) / 2; - Part::GeomPoint* point = new Part::GeomPoint(p); - point->Construction = true; - return point; - } - else if (!infinite) { - Part::GeomLineSegment* line = new Part::GeomLineSegment(); - line->setPoints(p1,p2); - line->Construction = true; - return line; - } else { - Part::GeomLine* line = new Part::GeomLine(); - line->setLine(p1, p2 - p1); - line->Construction = true; - return line; - } -} - -bool SketchObject::evaluateSupport(void) -{ - // returns false if the shape if broken, null or non-planar - Part::Feature *part = static_cast(Support.getValue()); - if (!part || !part->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) - return false; - - const std::vector &sub = Support.getSubValues(); - assert(sub.size()==1); - // get the selected sub shape (a Face) - const Part::TopoShape &shape = part->Shape.getShape(); - - if (shape._Shape.IsNull()) - return false; - - TopoDS_Shape sh; - try { - sh = shape.getSubShape(sub[0].c_str()); - } - catch (Standard_Failure) { - return false; - } - const TopoDS_Face &face = TopoDS::Face(sh); - if (face.IsNull()) - return false; - - BRepAdaptor_Surface adapt(face); - if (adapt.GetType() != GeomAbs_Plane) - return false; // No planar face - - return true; -} - -void SketchObject::validateExternalLinks(void) -{ - std::vector Objects = ExternalGeometry.getValues(); - std::vector SubElements = ExternalGeometry.getSubValues(); - - bool rebuild = false ; - - for (int i=0; i < int(Objects.size()); i++) { - const App::DocumentObject *Obj=Objects[i]; - const std::string SubElement=SubElements[i]; - - const Part::Feature *refObj=static_cast(Obj); - const Part::TopoShape& refShape=refObj->Shape.getShape(); - - TopoDS_Shape refSubShape; - try { - refSubShape = refShape.getSubShape(SubElement.c_str()); - } - catch (Standard_Failure) { - rebuild = true ; - Objects.erase(Objects.begin()+i); - SubElements.erase(SubElements.begin()+i); - - const std::vector< Constraint * > &constraints = Constraints.getValues(); - std::vector< Constraint * > newConstraints(0); - int GeoId = -3 - i; - for (std::vector::const_iterator it = constraints.begin(); - it != constraints.end(); ++it) { - if ((*it)->First != GeoId && (*it)->Second != GeoId && (*it)->Third != GeoId) { - Constraint *copiedConstr = (*it)->clone(); - if (copiedConstr->First < GeoId && - copiedConstr->First != Constraint::GeoUndef) - copiedConstr->First += 1; - if (copiedConstr->Second < GeoId && - copiedConstr->Second != Constraint::GeoUndef) - copiedConstr->Second += 1; - if (copiedConstr->Third < GeoId && - copiedConstr->Third != Constraint::GeoUndef) - copiedConstr->Third += 1; - - newConstraints.push_back(copiedConstr); - } - } - - Constraints.setValues(newConstraints); - i--; // we deleted an item, so the next one took its place - } - } - - if (rebuild) { - ExternalGeometry.setValues(Objects,SubElements); - rebuildExternalGeometry(); - Constraints.acceptGeometry(getCompleteGeometry()); - rebuildVertexIndex(); - solve(true); // we have to update this sketch and everything depending on it. - } - -} - -void SketchObject::rebuildExternalGeometry(void) -{ - // get the actual lists of the externals - std::vector Objects = ExternalGeometry.getValues(); - std::vector SubElements = ExternalGeometry.getSubValues(); - - Base::Placement Plm = Placement.getValue(); - Base::Vector3d Pos = Plm.getPosition(); - Base::Rotation Rot = Plm.getRotation(); - Base::Vector3d dN(0,0,1); - Rot.multVec(dN,dN); - Base::Vector3d dX(1,0,0); - Rot.multVec(dX,dX); - - Base::Placement invPlm = Plm.inverse(); - Base::Matrix4D invMat = invPlm.toMatrix(); - gp_Trsf mov; - mov.SetValues(invMat[0][0],invMat[0][1],invMat[0][2],invMat[0][3], - invMat[1][0],invMat[1][1],invMat[1][2],invMat[1][3], - invMat[2][0],invMat[2][1],invMat[2][2],invMat[2][3] -#if OCC_VERSION_HEX < 0x060800 - , 0.00001, 0.00001 -#endif - ); //precision was removed in OCCT CR0025194 - - gp_Ax3 sketchAx3(gp_Pnt(Pos.x,Pos.y,Pos.z), - gp_Dir(dN.x,dN.y,dN.z), - gp_Dir(dX.x,dX.y,dX.z)); - gp_Pln sketchPlane(sketchAx3); - - Handle(Geom_Plane) gPlane = new Geom_Plane(sketchPlane); - BRepBuilderAPI_MakeFace mkFace(sketchPlane); - TopoDS_Shape aProjFace = mkFace.Shape(); - - for (std::vector::iterator it=ExternalGeo.begin(); it != ExternalGeo.end(); ++it) - if (*it) delete *it; - ExternalGeo.clear(); - Part::GeomLineSegment *HLine = new Part::GeomLineSegment(); - Part::GeomLineSegment *VLine = new Part::GeomLineSegment(); - HLine->setPoints(Base::Vector3d(0,0,0),Base::Vector3d(1,0,0)); - VLine->setPoints(Base::Vector3d(0,0,0),Base::Vector3d(0,1,0)); - HLine->Construction = true; - VLine->Construction = true; - ExternalGeo.push_back(HLine); - ExternalGeo.push_back(VLine); - for (int i=0; i < int(Objects.size()); i++) { - const App::DocumentObject *Obj=Objects[i]; - const std::string SubElement=SubElements[i]; - - TopoDS_Shape refSubShape; - - if (Obj->getTypeId().isDerivedFrom(Part::Datum::getClassTypeId())) { - const Part::Datum* datum = static_cast(Obj); - refSubShape = datum->Shape.getValue(); - } else if (Obj->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) { - try { - const Part::Feature *refObj=static_cast(Obj); - const Part::TopoShape& refShape=refObj->Shape.getShape(); - refSubShape = refShape.getSubShape(SubElement.c_str()); - } - catch (Standard_Failure) { - Handle_Standard_Failure e = Standard_Failure::Caught(); - throw Base::Exception(e->GetMessageString()); - } - } else if (Obj->getTypeId().isDerivedFrom(App::Plane::getClassTypeId())) { - const App::Plane* pl = static_cast(Obj); - Base::Placement plm = pl->Placement.getValue(); - Base::Vector3d base = plm.getPosition(); - Base::Rotation rot = plm.getRotation(); - Base::Vector3d normal(0,0,1); - rot.multVec(normal, normal); - gp_Pln plane(gp_Pnt(base.x,base.y,base.z), gp_Dir(normal.x, normal.y, normal.z)); - BRepBuilderAPI_MakeFace fBuilder(plane); - if (!fBuilder.IsDone()) - throw Base::Exception("Sketcher: addExternal(): Failed to build face from App::Plane"); - - TopoDS_Face f = TopoDS::Face(fBuilder.Shape()); - refSubShape = f; - } else { - throw Base::Exception("Datum feature type is not yet supported as external geometry for a sketch"); - } - - switch (refSubShape.ShapeType()) - { - case TopAbs_FACE: - { - const TopoDS_Face& face = TopoDS::Face(refSubShape); - BRepAdaptor_Surface surface(face); - if (surface.GetType() == GeomAbs_Plane) { - // Check that the plane is perpendicular to the sketch plane - Geom_Plane plane = surface.Plane(); - gp_Dir dnormal = plane.Axis().Direction(); - gp_Dir snormal = sketchPlane.Axis().Direction(); - if (fabs(dnormal.Angle(snormal) - M_PI_2) < Precision::Confusion()) { - // Get vector that is normal to both sketch plane normal and plane normal. This is the line's direction - gp_Dir lnormal = dnormal.Crossed(snormal); - BRepBuilderAPI_MakeEdge builder(gp_Lin(plane.Location(), lnormal)); - builder.Build(); - if (builder.IsDone()) { - const TopoDS_Edge& edge = TopoDS::Edge(builder.Shape()); - BRepAdaptor_Curve curve(edge); - if (curve.GetType() == GeomAbs_Line) { - ExternalGeo.push_back(projectLine(curve, gPlane, invPlm)); - } - } - - } - } else { - throw Base::Exception("Non-planar faces are not yet supported for external geometry of sketches"); - } - } - break; - case TopAbs_EDGE: - { - const TopoDS_Edge& edge = TopoDS::Edge(refSubShape); - BRepAdaptor_Curve curve(edge); - if (curve.GetType() == GeomAbs_Line) { - ExternalGeo.push_back(projectLine(curve, gPlane, invPlm)); - } - else if (curve.GetType() == GeomAbs_Circle) { - gp_Dir vec1 = sketchPlane.Axis().Direction(); - gp_Dir vec2 = curve.Circle().Axis().Direction(); - if (vec1.IsParallel(vec2, Precision::Confusion())) { - gp_Circ circle = curve.Circle(); - gp_Pnt cnt = circle.Location(); - gp_Pnt beg = curve.Value(curve.FirstParameter()); - gp_Pnt end = curve.Value(curve.LastParameter()); - - GeomAPI_ProjectPointOnSurf proj(cnt,gPlane); - cnt = proj.NearestPoint(); - circle.SetLocation(cnt); - cnt.Transform(mov); - circle.Transform(mov); - - if (beg.SquareDistance(end) < Precision::Confusion()) { - Part::GeomCircle* gCircle = new Part::GeomCircle(); - gCircle->setRadius(circle.Radius()); - gCircle->setCenter(Base::Vector3d(cnt.X(),cnt.Y(),cnt.Z())); - - gCircle->Construction = true; - ExternalGeo.push_back(gCircle); - } - else { - Part::GeomArcOfCircle* gArc = new Part::GeomArcOfCircle(); - Handle_Geom_Curve hCircle = new Geom_Circle(circle); - Handle_Geom_TrimmedCurve tCurve = new Geom_TrimmedCurve(hCircle, curve.FirstParameter(), - curve.LastParameter()); - gArc->setHandle(tCurve); - gArc->Construction = true; - ExternalGeo.push_back(gArc); - } - } - else { - // creates an ellipse - throw Base::Exception("Not yet supported geometry for external geometry"); - } - } - else { - try { - BRepOffsetAPI_NormalProjection mkProj(aProjFace); - mkProj.Add(edge); - mkProj.Build(); - const TopoDS_Shape& projShape = mkProj.Projection(); - if (!projShape.IsNull()) { - TopExp_Explorer xp; - for (xp.Init(projShape, TopAbs_EDGE); xp.More(); xp.Next()) { - TopoDS_Edge projEdge = TopoDS::Edge(xp.Current()); - TopLoc_Location loc(mov); - projEdge.Location(loc); - BRepAdaptor_Curve projCurve(projEdge); - if (projCurve.GetType() == GeomAbs_Line) { - gp_Pnt P1 = projCurve.Value(projCurve.FirstParameter()); - gp_Pnt P2 = projCurve.Value(projCurve.LastParameter()); - Base::Vector3d p1(P1.X(),P1.Y(),P1.Z()); - Base::Vector3d p2(P2.X(),P2.Y(),P2.Z()); - - if (Base::Distance(p1,p2) < Precision::Confusion()) { - Base::Vector3d p = (p1 + p2) / 2; - Part::GeomPoint* point = new Part::GeomPoint(p); - point->Construction = true; - ExternalGeo.push_back(point); - } - else { - Part::GeomLineSegment* line = new Part::GeomLineSegment(); - line->setPoints(p1,p2); - line->Construction = true; - ExternalGeo.push_back(line); - } - } - else if (projCurve.GetType() == GeomAbs_Circle) { - gp_Circ c = projCurve.Circle(); - gp_Pnt p = c.Location(); - gp_Pnt P1 = projCurve.Value(projCurve.FirstParameter()); - gp_Pnt P2 = projCurve.Value(projCurve.LastParameter()); - - if (P1.SquareDistance(P2) < Precision::Confusion()) { - Part::GeomCircle* circle = new Part::GeomCircle(); - circle->setRadius(c.Radius()); - circle->setCenter(Base::Vector3d(p.X(),p.Y(),p.Z())); - - circle->Construction = true; - ExternalGeo.push_back(circle); - } - else { - Part::GeomArcOfCircle* arc = new Part::GeomArcOfCircle(); - Handle_Geom_Curve curve = new Geom_Circle(c); - Handle_Geom_TrimmedCurve tCurve = new Geom_TrimmedCurve(curve, projCurve.FirstParameter(), - projCurve.LastParameter()); - arc->setHandle(tCurve); - arc->Construction = true; - ExternalGeo.push_back(arc); - } - } - else if (projCurve.GetType() == GeomAbs_Ellipse) { - gp_Elips e = projCurve.Ellipse(); - gp_Pnt p = e.Location(); - gp_Pnt P1 = projCurve.Value(projCurve.FirstParameter()); - gp_Pnt P2 = projCurve.Value(projCurve.LastParameter()); - - //gp_Dir normal = e.Axis().Direction(); - gp_Dir normal = gp_Dir(0,0,1); - gp_Ax2 xdirref(p, normal); - - if (P1.SquareDistance(P2) < Precision::Confusion()) { - Part::GeomEllipse* ellipse = new Part::GeomEllipse(); - Handle_Geom_Ellipse curve = new Geom_Ellipse(e); - ellipse->setHandle(curve); - ellipse->Construction = true; - ExternalGeo.push_back(ellipse); - } - else { - Part::GeomArcOfEllipse* aoe = new Part::GeomArcOfEllipse(); - Handle_Geom_Curve curve = new Geom_Ellipse(e); - Handle_Geom_TrimmedCurve tCurve = new Geom_TrimmedCurve(curve, projCurve.FirstParameter(), - projCurve.LastParameter()); - aoe->setHandle(tCurve); - aoe->Construction = true; - ExternalGeo.push_back(aoe); - } - } - else { - throw Base::Exception("Not yet supported geometry for external geometry"); - } - } - } - } - catch (Standard_Failure) { - Handle_Standard_Failure e = Standard_Failure::Caught(); - throw Base::Exception(e->GetMessageString()); - } - } - } - break; - case TopAbs_VERTEX: - { - gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(refSubShape)); - GeomAPI_ProjectPointOnSurf proj(P,gPlane); - P = proj.NearestPoint(); - Base::Vector3d p(P.X(),P.Y(),P.Z()); - invPlm.multVec(p,p); - - Part::GeomPoint* point = new Part::GeomPoint(p); - point->Construction = true; - ExternalGeo.push_back(point); - } - break; - default: - throw Base::Exception("Unknown type of geometry"); - break; - } - } - - rebuildVertexIndex(); -} - -std::vector SketchObject::getCompleteGeometry(void) const -{ - std::vector vals=getInternalGeometry(); - vals.insert(vals.end(), ExternalGeo.rbegin(), ExternalGeo.rend()); // in reverse order - return vals; -} - -void SketchObject::rebuildVertexIndex(void) -{ - VertexId2GeoId.resize(0); - VertexId2PosId.resize(0); - int imax=getHighestCurveIndex(); - int i=0; - const std::vector< Part::Geometry * > geometry = getCompleteGeometry(); - if (geometry.size() <= 2) - return; - for (std::vector< Part::Geometry * >::const_iterator it = geometry.begin(); - it != geometry.end()-2; ++it, i++) { - if (i > imax) - i = -getExternalGeometryCount(); - if ((*it)->getTypeId() == Part::GeomPoint::getClassTypeId()) { - VertexId2GeoId.push_back(i); - VertexId2PosId.push_back(start); - } else if ((*it)->getTypeId() == Part::GeomLineSegment::getClassTypeId()) { - VertexId2GeoId.push_back(i); - VertexId2PosId.push_back(start); - VertexId2GeoId.push_back(i); - VertexId2PosId.push_back(end); - } else if ((*it)->getTypeId() == Part::GeomCircle::getClassTypeId()) { - VertexId2GeoId.push_back(i); - VertexId2PosId.push_back(mid); - } else if ((*it)->getTypeId() == Part::GeomEllipse::getClassTypeId()) { - VertexId2GeoId.push_back(i); - VertexId2PosId.push_back(mid); - } else if ((*it)->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()) { - VertexId2GeoId.push_back(i); - VertexId2PosId.push_back(start); - VertexId2GeoId.push_back(i); - VertexId2PosId.push_back(end); - VertexId2GeoId.push_back(i); - VertexId2PosId.push_back(mid); - } else if ((*it)->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId()) { - VertexId2GeoId.push_back(i); - VertexId2PosId.push_back(start); - VertexId2GeoId.push_back(i); - VertexId2PosId.push_back(end); - VertexId2GeoId.push_back(i); - VertexId2PosId.push_back(mid); - } - } -} - -const std::vector< std::map > SketchObject::getCoincidenceGroups() -{ - // this function is different from that in getCoincidentPoints in that: - // - getCoincidentPoints only considers direct coincidence (the points that are linked via a single coincidence) - // - this function provides an array of maps of points, each map containing the points that are coincident by virtue - // of any number of interrelated coincidence constraints (if coincidence 1-2 and coincidence 2-3, {1,2,3} are in that set) - - const std::vector< Sketcher::Constraint * > &vals = Constraints.getValues(); - - std::vector< std::map > coincidenttree; - // push the constraints - for (std::vector< Sketcher::Constraint * >::const_iterator it= vals.begin();it != vals.end(); ++it) { - if( (*it)->Type == Sketcher::Coincident ) { - int firstpresentin=-1; - int secondpresentin=-1; - - int i=0; - - for(std::vector< std::map >::const_iterator iti = coincidenttree.begin(); iti != coincidenttree.end(); ++iti,i++) { - // First - std::map::const_iterator filiterator; - filiterator = (*iti).find((*it)->First); - if( filiterator != (*iti).end()) { - if((*it)->FirstPos == (*filiterator).second) - firstpresentin = i; - } - // Second - filiterator = (*iti).find((*it)->Second); - if( filiterator != (*iti).end()) { - if((*it)->SecondPos == (*filiterator).second) - secondpresentin = i; - } - } - - if ( firstpresentin!=-1 && secondpresentin!=-1) { - // we have to merge those sets into one - coincidenttree[firstpresentin].insert(coincidenttree[secondpresentin].begin(), coincidenttree[secondpresentin].end()); - coincidenttree.erase(coincidenttree.begin()+secondpresentin); - } - else if ( firstpresentin==-1 && secondpresentin==-1 ) { - // we do not have any of the values, so create a setCursor - std::map tmp; - tmp.insert(std::pair((*it)->First,(*it)->FirstPos)); - tmp.insert(std::pair((*it)->Second,(*it)->SecondPos)); - coincidenttree.push_back(tmp); - } - else if ( firstpresentin != -1 ) { - // add to existing group - coincidenttree[firstpresentin].insert(std::pair((*it)->Second,(*it)->SecondPos)); - } - else { // secondpresentin != -1 - // add to existing group - coincidenttree[secondpresentin].insert(std::pair((*it)->First,(*it)->FirstPos)); - } - - } - } - - return coincidenttree; -} - -void SketchObject::isCoincidentWithExternalGeometry(int GeoId, bool &start_external, bool &mid_external, bool &end_external) { - - start_external=false; - mid_external=false; - end_external=false; - - const std::vector< std::map > coincidenttree = getCoincidenceGroups(); - - for(std::vector< std::map >::const_iterator it = coincidenttree.begin(); it != coincidenttree.end(); ++it) { - - std::map::const_iterator geoId1iterator; - - geoId1iterator = (*it).find(GeoId); - - if( geoId1iterator != (*it).end()) { - // If First is in this set and the first key in this ordered element key is external - if( (*it).begin()->first < 0 ) { - if( (*geoId1iterator).second == Sketcher::start ) - start_external=true; - else if ( (*geoId1iterator).second == Sketcher::mid ) - mid_external=true; - else if ( (*geoId1iterator).second == Sketcher::end ) - end_external=true; - } - } - } -} - -const std::map SketchObject::getAllCoincidentPoints(int GeoId, PointPos PosId) { - - const std::vector< std::map > coincidenttree = getCoincidenceGroups(); - - for(std::vector< std::map >::const_iterator it = coincidenttree.begin(); it != coincidenttree.end(); ++it) { - - std::map::const_iterator geoId1iterator; - - geoId1iterator = (*it).find(GeoId); - - if( geoId1iterator != (*it).end()) { - // If GeoId is in this set - - if ((*geoId1iterator).second == PosId) // and posId matches - return (*it); - } - } - - std::map empty; - - return empty; -} - - -void SketchObject::getDirectlyCoincidentPoints(int GeoId, PointPos PosId, std::vector &GeoIdList, - std::vector &PosIdList) -{ - const std::vector &constraints = this->Constraints.getValues(); - - GeoIdList.clear(); - PosIdList.clear(); - GeoIdList.push_back(GeoId); - PosIdList.push_back(PosId); - for (std::vector::const_iterator it=constraints.begin(); - it != constraints.end(); ++it) { - if ((*it)->Type == Sketcher::Coincident) { - if ((*it)->First == GeoId && (*it)->FirstPos == PosId) { - GeoIdList.push_back((*it)->Second); - PosIdList.push_back((*it)->SecondPos); - } - else if ((*it)->Second == GeoId && (*it)->SecondPos == PosId) { - GeoIdList.push_back((*it)->First); - PosIdList.push_back((*it)->FirstPos); - } - } - } - if (GeoIdList.size() == 1) { - GeoIdList.clear(); - PosIdList.clear(); - } -} - -void SketchObject::getDirectlyCoincidentPoints(int VertexId, std::vector &GeoIdList, - std::vector &PosIdList) -{ - int GeoId; - PointPos PosId; - getGeoVertexIndex(VertexId, GeoId, PosId); - getDirectlyCoincidentPoints(GeoId, PosId, GeoIdList, PosIdList); -} - -bool SketchObject::arePointsCoincident(int GeoId1, PointPos PosId1, - int GeoId2, PointPos PosId2) -{ - if (GeoId1 == GeoId2 && PosId1 == PosId2) - return true; - - const std::vector< std::map > coincidenttree = getCoincidenceGroups(); - - for(std::vector< std::map >::const_iterator it = coincidenttree.begin(); it != coincidenttree.end(); ++it) { - - std::map::const_iterator geoId1iterator; - - geoId1iterator = (*it).find(GeoId1); - - if( geoId1iterator != (*it).end()) { - // If First is in this set - std::map::const_iterator geoId2iterator; - - geoId2iterator = (*it).find(GeoId2); - - if( geoId2iterator != (*it).end()) { - // If Second is in this set - if ((*geoId1iterator).second == PosId1 && - (*geoId2iterator).second == PosId2) - return true; - } - } - } - - return false; -} - -void SketchObject::appendConflictMsg(const std::vector &conflicting, std::string &msg) -{ - std::stringstream ss; - if (msg.length() > 0) - ss << msg; - if (conflicting.size() > 0) { - if (conflicting.size() == 1) - ss << "Please remove the following constraint:\n"; - else - ss << "Please remove at least one of the following constraints:\n"; - ss << conflicting[0]; - for (unsigned int i=1; i < conflicting.size(); i++) - ss << ", " << conflicting[i]; - ss << "\n"; - } - msg = ss.str(); -} - -void SketchObject::appendRedundantMsg(const std::vector &redundant, std::string &msg) -{ - std::stringstream ss; - if (msg.length() > 0) - ss << msg; - if (redundant.size() > 0) { - if (redundant.size() == 1) - ss << "Please remove the following redundant constraint:\n"; - else - ss << "Please remove the following redundant constraints:\n"; - ss << redundant[0]; - for (unsigned int i=1; i < redundant.size(); i++) - ss << ", " << redundant[i]; - ss << "\n"; - } - msg = ss.str(); -} - -bool SketchObject::evaluateConstraint(const Constraint *constraint) const -{ - //if requireXXX, GeoUndef is treated as an error. If not requireXXX, - //GeoUndef is accepted. Index range checking is done on everything regardless. - bool requireFirst = true; - bool requireSecond = false; - bool requireThird = false; - - switch (constraint->Type) { - case Radius: - requireFirst = true; - break; - case Horizontal: - case Vertical: - requireFirst = true; - break; - case Distance: - case DistanceX: - case DistanceY: - requireFirst = true; - break; - case Coincident: - case Perpendicular: - case Parallel: - case Equal: - case PointOnObject: - case Tangent: - requireFirst = true; - requireSecond = true; - break; - case Symmetric: - requireFirst = true; - requireSecond = true; - requireThird = true; - break; - case Angle: - requireFirst = true; - break; - case SnellsLaw: - requireFirst = true; - requireSecond = true; - requireThird = true; - break; - default: - break; - } - - int intGeoCount = getHighestCurveIndex() + 1; - int extGeoCount = getExternalGeometryCount(); - - //the actual checks - bool ret = true; - int geoId; - geoId = constraint->First; - ret = ret && ((geoId == Constraint::GeoUndef && !requireFirst) - || - (geoId >= -extGeoCount && geoId < intGeoCount) ); - - geoId = constraint->Second; - ret = ret && ((geoId == Constraint::GeoUndef && !requireSecond) - || - (geoId >= -extGeoCount && geoId < intGeoCount) ); - - geoId = constraint->Third; - ret = ret && ((geoId == Constraint::GeoUndef && !requireThird) - || - (geoId >= -extGeoCount && geoId < intGeoCount) ); - - return ret; -} - -bool SketchObject::evaluateConstraints() const -{ - int intGeoCount = getHighestCurveIndex() + 1; - int extGeoCount = getExternalGeometryCount(); - - std::vector geometry = getCompleteGeometry(); - const std::vector& constraints = Constraints.getValuesForce(); - if (static_cast(geometry.size()) != extGeoCount + intGeoCount) - return false; - if (geometry.size() < 2) - return false; - - std::vector::const_iterator it; - for (it = constraints.begin(); it != constraints.end(); ++it) { - if (!evaluateConstraint(*it)) - return false; - } - - if(constraints.size()>0){ - if (!Constraints.scanGeometry(geometry)) return false; - } - - return true; -} - -void SketchObject::validateConstraints() -{ - std::vector geometry = getCompleteGeometry(); - const std::vector& constraints = Constraints.getValues(); - - std::vector newConstraints; - std::vector::const_iterator it; - for (it = constraints.begin(); it != constraints.end(); ++it) { - bool valid = evaluateConstraint(*it); - if (valid) - newConstraints.push_back(*it); - } - - if (newConstraints.size() != constraints.size()) { - Constraints.setValues(newConstraints); - acceptGeometry(); - } -} - -std::string SketchObject::validateExpression(const App::ObjectIdentifier &path, boost::shared_ptr expr) -{ - const App::Property * prop = path.getProperty(); - - assert(expr != 0); - - if (!prop) - return "Property not found"; - - if (prop == &Constraints) { - const Constraint * constraint = Constraints.getConstraint(path); - - if (!constraint->isDriving) - return "Reference constraints cannot be set!"; - } - - std::set deps; - expr->getDeps(deps); - - for (std::set::const_iterator i = deps.begin(); i != deps.end(); ++i) { - const App::Property * prop = (*i).getProperty(); - - if (prop == &Constraints) { - const Constraint * constraint = Constraints.getConstraint(*i); - - if (!constraint->isDriving) - return "Reference constraint from this sketch cannot be used in this expression."; - } - } - return ""; -} - -//This function is necessary for precalculation of an angle when adding -// an angle constraint. It is also used here, in SketchObject, to -// lock down the type of tangency/perpendicularity. -double SketchObject::calculateAngleViaPoint(int GeoId1, int GeoId2, double px, double py) -{ - // Temporary sketch based calculation. Slow, but guaranteed consistency with constraints. - Sketcher::Sketch sk; - - const Part::Geometry *p1=this->getGeometry(GeoId1); - const Part::Geometry *p2=this->getGeometry(GeoId2); - - if(p1!=0 && p2!=0) { - int i1 = sk.addGeometry(this->getGeometry(GeoId1)); - int i2 = sk.addGeometry(this->getGeometry(GeoId2)); - - return sk.calculateAngleViaPoint(i1,i2,px,py); - } - else - throw Base::Exception("Null geometry in calculateAngleViaPoint"); - -/* - // OCC-based calculation. It is faster, but it was removed due to problems - // with reversed geometry (clockwise arcs). More info in "Sketch: how to - // handle reversed external arcs?" forum thread - // http://forum.freecadweb.org/viewtopic.php?f=10&t=9130&sid=1b994fa1236db5ac2371eeb9a53de23f - - const Part::GeomCurve &g1 = *(dynamic_cast(this->getGeometry(GeoId1))); - const Part::GeomCurve &g2 = *(dynamic_cast(this->getGeometry(GeoId2))); - Base::Vector3d p(px, py, 0.0); - - double u1 = 0.0; - double u2 = 0.0; - if (! g1.closestParameterToBasicCurve(p, u1) ) throw Base::Exception("SketchObject::calculateAngleViaPoint: closestParameter(curve1) failed!"); - if (! g2.closestParameterToBasicCurve(p, u2) ) throw Base::Exception("SketchObject::calculateAngleViaPoint: closestParameter(curve2) failed!"); - - gp_Dir tan1, tan2; - if (! g1.tangent(u1,tan1) ) throw Base::Exception("SketchObject::calculateAngleViaPoint: tangent1 failed!"); - if (! g2.tangent(u2,tan2) ) throw Base::Exception("SketchObject::calculateAngleViaPoint: tangent2 failed!"); - - assert(abs(tan1.Z())<0.0001); - assert(abs(tan2.Z())<0.0001); - - double ang = atan2(-tan2.X()*tan1.Y()+tan2.Y()*tan1.X(), tan2.X()*tan1.X() + tan2.Y()*tan1.Y()); - return ang; -*/ -} - -void SketchObject::constraintsRenamed(const std::map &renamed) -{ - ExpressionEngine.renameExpressions(renamed); - - getDocument()->renameObjectIdentifiers(renamed); -} - -void SketchObject::constraintsRemoved(const std::set &removed) -{ - std::set::const_iterator i = removed.begin(); - - while (i != removed.end()) { - ExpressionEngine.setValue(*i, boost::shared_ptr(), 0); - ++i; - } -} - -//Tests if the provided point lies exactly in a curve (satisfies -// point-on-object constraint). It is used to decide whether it is nesessary to -// constrain a point onto curves when 3-element selection tangent-via-point-like -// constraints are applied. -bool SketchObject::isPointOnCurve(int geoIdCurve, double px, double py) -{ - //DeepSOIC: this may be slow, but I wanted to reuse the existing code - Sketcher::Sketch sk; - int icrv = sk.addGeometry(this->getGeometry(geoIdCurve)); - Base::Vector3d pp; - pp.x = px; pp.y = py; - Part::GeomPoint p(pp); - int ipnt = sk.addPoint(p); - int icstr = sk.addPointOnObjectConstraint(ipnt, Sketcher::start, icrv); - double err = sk.calculateConstraintError(icstr); - return err*err < 10.0*sk.getSolverPrecision(); -} - -//This one was done just for fun to see to what precision the constraints are solved. -double SketchObject::calculateConstraintError(int ConstrId) -{ - Sketcher::Sketch sk; - const std::vector &clist = this->Constraints.getValues(); - if (ConstrId < 0 || ConstrId >= int(clist.size())) - return std::numeric_limits::quiet_NaN(); - - Constraint* cstr = clist[ConstrId]->clone(); - double result=0.0; - try{ - std::vector GeoIdList; - int g; - GeoIdList.push_back(cstr->First); - GeoIdList.push_back(cstr->Second); - GeoIdList.push_back(cstr->Third); - - //add only necessary geometry to the sketch - for(std::size_t i=0; igetGeometry(g)); - } - } - - cstr->First = GeoIdList[0]; - cstr->Second = GeoIdList[1]; - cstr->Third = GeoIdList[2]; - int icstr = sk.addConstraint(cstr); - result = sk.calculateConstraintError(icstr); - } catch(...) {//cleanup - delete cstr; - throw; - } - delete cstr; - return result; -} - -PyObject *SketchObject::getPyObject(void) -{ - if (PythonObject.is(Py::_None())) { - // ref counter is set to 1 - PythonObject = Py::Object(new SketchObjectPy(this),true); - } - return Py::new_reference_to(PythonObject); -} - -unsigned int SketchObject::getMemSize(void) const -{ - return 0; -} - -void SketchObject::Save(Writer &writer) const -{ - // save the father classes - Part::Part2DObject::Save(writer); -} - -void SketchObject::Restore(XMLReader &reader) -{ - // read the father classes - Part::Part2DObject::Restore(reader); -} - -void SketchObject::onChanged(const App::Property* prop) -{ - if (isRestoring() && prop == &Geometry) { - std::vector geom = Geometry.getValues(); - std::vector supportedGeom = supportedGeometry(geom); - // To keep upward compatibility ignore unsupported geometry types - if (supportedGeom.size() != geom.size()) { - Geometry.setValues(supportedGeom); - return; - } - } - if (prop == &Geometry || prop == &Constraints) { - Constraints.checkGeometry(getCompleteGeometry()); - } - else if (prop == &ExternalGeometry) { - // make sure not to change anything while restoring this object - if (!isRestoring()) { - // external geometry was cleared - if (ExternalGeometry.getSize() == 0) { - delConstraintsToExternal(); - } - } - } -#if 0 - // For now do not delete anything (#0001791). When changing the support - // face it might be better to check which external geometries can be kept. - else if (prop == &Support) { - // make sure not to change anything while restoring this object - if (!isRestoring()) { - // if support face has changed then clear the external geometry - delConstraintsToExternal(); - for (int i=0; i < getExternalGeometryCount(); i++) { - delExternal(0); - } - } - } -#endif - Part::Part2DObject::onChanged(prop); -} - -void SketchObject::onDocumentRestored() -{ - try { - if(Support.getValue()) { - validateExternalLinks(); - rebuildExternalGeometry(); - } - else { - rebuildVertexIndex(); - } - Constraints.acceptGeometry(getCompleteGeometry()); - } - catch (...) { - } -} - -void SketchObject::getGeoVertexIndex(int VertexId, int &GeoId, PointPos &PosId) const -{ - if (VertexId < 0 || VertexId >= int(VertexId2GeoId.size())) { - GeoId = Constraint::GeoUndef; - PosId = none; - return; - } - GeoId = VertexId2GeoId[VertexId]; - PosId = VertexId2PosId[VertexId]; -} - -int SketchObject::getVertexIndexGeoPos(int GeoId, PointPos PosId) const -{ - for(std::size_t i=0;i &vals = this->Constraints.getValues(); - - std::vector< Constraint * > newVals(vals);//modifiable copy of pointers array - - std::vector< Constraint * > tbd;//list of temporary Constraint copies that need to be deleted later - - for(std::size_t i = 0; iType == Tangent || newVals[i]->Type == Perpendicular ){ - //create a constraint copy, affect it, replace the pointer - cntToBeAffected++; - Constraint *constNew = newVals[i]->clone(); - bool ret = AutoLockTangencyAndPerpty(constNew, /*bForce=*/true, bLock); - if (ret) cntSuccess++; - tbd.push_back(constNew); - newVals[i] = constNew; - Base::Console().Log("Constraint%i will be affected\n", - i+1); - } - } - - this->Constraints.setValues(newVals); - - //clean up - delete temporary copies of constraints that were made to affect the constraints - for(std::size_t i=0; i &vals = this->Constraints.getValues(); - - std::vector< Constraint * > newVals(vals);//modifiable copy of pointers array - - std::vector< Constraint * > tbd;//list of temporary Constraint copies that need to be deleted later - - for(std::size_t ic = 0; icFirst; posId = newVals[ic]->FirstPos; break; - case 2: geoId=newVals[ic]->Second; posId = newVals[ic]->SecondPos; break; - case 3: geoId=newVals[ic]->Third; posId = newVals[ic]->ThirdPos; break; - } - - if ( geoId <= -3 && - (posId==Sketcher::start || posId==Sketcher::end)){ - //we are dealing with a link to an endpoint of external geom - Part::Geometry* g = this->ExternalGeo[-geoId-1]; - if (g->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()){ - const Part::GeomArcOfCircle *segm = dynamic_cast(g); - if(segm->isReversedInXY()){ - //Gotcha! a link to an endpoint of external arc that is reversed. - //create a constraint copy, affect it, replace the pointer - if (!affected) - constNew = newVals[ic]->clone(); - affected=true; - //Do the fix on temp vars - if(posId == Sketcher::start) - posId = Sketcher::end; - else if (posId == Sketcher::end) - posId = Sketcher::start; - } - } - } - if (!affected) continue; - //Propagate the fix made on temp vars to the constraint - switch (ig){ - case 1: constNew->First = geoId; constNew->FirstPos = posId; break; - case 2: constNew->Second = geoId; constNew->SecondPos = posId; break; - case 3: constNew->Third = geoId; constNew->ThirdPos = posId; break; - } - } - if (affected){ - cntToBeAffected++; - tbd.push_back(constNew); - newVals[ic] = constNew; - Base::Console().Log("Constraint%i will be affected\n", - ic+1); - }; - } - - if(!justAnalyze){ - this->Constraints.setValues(newVals); - Base::Console().Log("Swapped start/end of reversed external arcs in %i constraints\n", - cntToBeAffected); - } - - //clean up - delete temporary copies of constraints that were made to affect the constraints - for(std::size_t i=0; iType == Tangent || cstr->Type == Perpendicular); - if(cstr->getValue() != 0.0 && ! bForce) /*tangency type already set. If not bForce - don't touch.*/ - return true; - if(!bLock){ - cstr->setValue(0.0);//reset - } else { - //decide on tangency type. Write the angle value into the datum field of the constraint. - int geoId1, geoId2, geoIdPt; - PointPos posPt; - geoId1 = cstr->First; - geoId2 = cstr->Second; - geoIdPt = cstr->Third; - posPt = cstr->ThirdPos; - if (geoIdPt == Constraint::GeoUndef){//not tangent-via-point, try endpoint-to-endpoint... - geoIdPt = cstr->First; - posPt = cstr->FirstPos; - } - if (posPt == none){//not endpoint-to-curve and not endpoint-to-endpoint tangent (is simple tangency) - //no tangency lockdown is implemented for simple tangency. Do nothing. - return false; - } else { - Base::Vector3d p = getPoint(geoIdPt, posPt); - - //this piece of code is also present in Sketch.cpp, correct for offset - //and to do the autodecision for old sketches. - double angleOffset = 0.0;//the difference between the datum value and the actual angle to apply. (datum=angle+offset) - double angleDesire = 0.0;//the desired angle value (and we are to decide if 180* should be added to it) - if (cstr->Type == Tangent) {angleOffset = -M_PI/2; angleDesire = 0.0;} - if (cstr->Type == Perpendicular) {angleOffset = 0; angleDesire = M_PI/2;} - - double angleErr = calculateAngleViaPoint(geoId1, geoId2, p.x, p.y) - angleDesire; - - //bring angleErr to -pi..pi - if (angleErr > M_PI) angleErr -= M_PI*2; - if (angleErr < -M_PI) angleErr += M_PI*2; - - //the autodetector - if(fabs(angleErr) > M_PI/2 ) - angleDesire += M_PI; - - cstr->setValue(angleDesire + angleOffset); //external tangency. The angle stored is offset by Pi/2 so that a value of 0.0 is invalid and threated as "undecided". - } - } - } catch (Base::Exception& e){ - //failure to determine tangency type is not a big deal, so a warning. - Base::Console().Warning("Error in AutoLockTangency. %s \n", e.what()); - return false; - } - return true; -} - -void SketchObject::setExpression(const App::ObjectIdentifier &path, boost::shared_ptr expr, const char * comment) -{ - DocumentObject::setExpression(path, expr, comment); - - if(noRecomputes) // if we do not have a recompute, the sketch must be solved to update the DoF of the solver, constraints and UI - solve(); -} - - -// Python Sketcher feature --------------------------------------------------------- - -namespace App { -/// @cond DOXERR -PROPERTY_SOURCE_TEMPLATE(Sketcher::SketchObjectPython, Sketcher::SketchObject) -template<> const char* Sketcher::SketchObjectPython::getViewProviderName(void) const { - return "SketcherGui::ViewProviderPython"; -} -template<> PyObject* Sketcher::SketchObjectPython::getPyObject(void) { - if (PythonObject.is(Py::_None())) { - // ref counter is set to 1 - PythonObject = Py::Object(new FeaturePythonPyT(this),true); - } - return Py::new_reference_to(PythonObject); -} -/// @endcond - -// explicit template instantiation -template class SketcherExport FeaturePythonT; -}