Merge branch 'refs/heads/master' into jriegel/develop-fem

Conflicts:
	src/Gui/View3DInventor.cpp same fix, but master was better
This commit is contained in:
jriegel 2013-09-04 07:47:08 +02:00
commit f18277ff46
176 changed files with 15441 additions and 4570 deletions

10
.gitignore vendored
View File

@ -1,3 +1,13 @@
# file types to ignore
*.pyc
*~
CMakeFiles/
*qrc.depends
qrc_*.cpp
ui_*.h
moc_*.cpp
Makefile
CMakeCache.txt
config.h
install_manifest.txt

View File

@ -71,6 +71,13 @@ endif(WIN32)
SET(CMAKE_INSTALL_DATADIR data CACHE PATH "Output directory for data and resource files")
SET(CMAKE_INSTALL_INCLUDEDIR include CACHE PATH "Output directory for header files")
SET(CMAKE_INSTALL_DOCDIR doc CACHE PATH "Output directory for documentation and license files")
SET(PYCXX_INCLUDE_DIR
"${CMAKE_SOURCE_DIR}/src" CACHE PATH
"Path to the directory containing PyCXX's CXX/Config.hxx include file")
SET(PYCXX_SOURCE_DIR
"${CMAKE_SOURCE_DIR}/src/CXX" CACHE PATH
"Path to the directory containing PyCXX's cxxextensions.c source file")
# used as compiler defines
SET(RESOURCEDIR "${CMAKE_INSTALL_DATADIR}")
@ -152,6 +159,10 @@ if(FREECAD_LIBPACK_USE)
message(SEND_ERROR "Could not find neither LibPack 6.x nor 7.x in specified location:" ${FREECAD_LIBPACK_DIR})
ENDIF(FREECAD_LIBPACK_CHECKFILE6X)
# -------------------------------- PyCXX --------------------------------
find_package(PyCXX REQUIRED)
# -------------------------------- Swig ----------------------------------
find_package(SWIG)
@ -204,6 +215,10 @@ MARK_AS_ADVANCED(FORCE FREECAD_LIBPACK_CHECKFILE6X FREECAD_LIBPACK_CHECKFILE7X)
find_package(ZLIB REQUIRED)
# -------------------------------- PyCXX --------------------------------
find_package(PyCXX REQUIRED)
# -------------------------------- OpenCasCade --------------------------------
#first, look for OpenCASCADE Community Edition (OCE)

108
cMake/FindPyCXX.cmake Normal file
View File

@ -0,0 +1,108 @@
# Locate PyCXX headers and source files
# This module defines
# PYCXX_INCLUDE_DIR
# PYCXX_SOURCE_DIR
# PYCXX_FOUND
# PYCXX_SOURCES
#
# The PYCXX_*_DIR variables can be set to tell this module where
# the files are.
# There's no standard location for PyCXX.
#
# The authors' example is to put it in "~\" [sic].
#
# Ubuntu puts the includes into /usr/include/python2.7/CXX and sources into
# /usr/share/python2.7/CXX.
#
# The Zultron Fedora RPM does the same as Ubuntu.
set(PYCXX_FOUND "YES")
# find the header directory
if(PYCXX_INCLUDE_DIR)
# headers better be in there
if(NOT EXISTS "${PYCXX_INCLUDE_DIR}/CXX/Config.hxx")
if(PyCXX_FIND_REQUIRED)
MESSAGE(FATAL_ERROR
"PyCXX: could not find CXX/Config.hxx in PYCXX_INCLUDE_DIR "
"${PYCXX_INCLUDE_DIR}")
else(PyCXX_FIND_REQUIRED)
MESSAGE(WARNING
"PyCXX: could not find CXX/Config.hxx in PYCXX_INCLUDE_DIR "
"${PYCXX_INCLUDE_DIR}")
unset(PYCXX_FOUND)
endif(PyCXX_FIND_REQUIRED)
endif(NOT EXISTS "${PYCXX_INCLUDE_DIR}/CXX/Config.hxx")
else(PYCXX_INCLUDE_DIR)
# check in 'standard' places
find_path(PYCXX_INCLUDE_DIR CXX/Config.hxx
${PYTHON_INCLUDE_DIR}
"${CMAKE_CURRENT_LIST_DIR}/..")
if(NOT PYCXX_INCLUDE_DIR)
if(PyCXX_FIND_REQUIRED)
MESSAGE(FATAL_ERROR
"PyCXX not found; please set PYCXX_INCLUDE_DIR to "
"the location of CXX/Config.hxx")
else(PyCXX_FIND_REQUIRED)
MESSAGE(STATUS "PyCXX not found")
unset(PYCXX_FOUND)
endif(PyCXX_FIND_REQUIRED)
endif(NOT PYCXX_INCLUDE_DIR)
endif(PYCXX_INCLUDE_DIR)
# find the sources directory
if(PYCXX_SOURCE_DIR)
# source directory specified, they'd better be there
if(NOT EXISTS "${PYCXX_SOURCE_DIR}/cxxextensions.c")
if(PyCXX_FIND_REQUIRED)
MESSAGE(FATAL_ERROR
"PyCXX: cxxextensions.c not found in PYCXX_INCLUDE_DIR "
"${PYCXX_INCLUDE_DIR}")
else(PyCXX_FIND_REQUIRED)
MESSAGE(WARNING
"PyCXX: cxxextensions.c not found in PYCXX_INCLUDE_DIR "
"${PYCXX_INCLUDE_DIR}")
unset(PYCXX_FOUND)
endif(PyCXX_FIND_REQUIRED)
endif(NOT EXISTS "${PYCXX_SOURCE_DIR}/cxxextensions.c")
else(PYCXX_SOURCE_DIR)
# check in 'standard' places
find_path(PYCXX_SOURCE_DIR cxxextensions.c
"${PYCXX_INCLUDE_DIR}/CXX"
"${PYCXX_INCLUDE_DIR}/Src"
"${PYTHON_INCLUDE_DIR}/CXX"
"${PYTHON_INCLUDE_DIR}/Src"
"${CMAKE_CURRENT_LIST_DIR}/../Src"
"${CMAKE_CURRENT_LIST_DIR}/../CXX")
if(NOT PYCXX_SOURCE_DIR)
if(PyCXX_FIND_REQUIRED)
MESSAGE(FATAL_ERROR
"PyCXX not found; please set PYCXX_SOURCE_DIR to "
"the location of cxxextensions.c")
else(PyCXX_FIND_REQUIRED)
MESSAGE(STATUS "PyCXX not found")
unset(PYCXX_FOUND)
endif(PyCXX_FIND_REQUIRED)
endif(NOT PYCXX_SOURCE_DIR)
endif(PYCXX_SOURCE_DIR)
# see what we've got
if(PYCXX_FOUND)
MESSAGE(STATUS "PyCXX found:")
MESSAGE(STATUS " Headers: ${PYCXX_INCLUDE_DIR}")
MESSAGE(STATUS " Sources: ${PYCXX_SOURCE_DIR}")
# Build the list of sources for convenience
set(PYCXX_SOURCES
${PYCXX_SOURCE_DIR}/cxxextensions.c
${PYCXX_SOURCE_DIR}/cxx_extensions.cxx
${PYCXX_SOURCE_DIR}/cxxsupport.cxx
${PYCXX_SOURCE_DIR}/IndirectPythonInterface.cxx
)
else(PYCXX_FOUND)
MESSAGE(STATUS "PyCXX not found")
endif(PYCXX_FOUND)

View File

@ -140,13 +140,13 @@ if(MSVC)
elseif(MINGW)
set_target_properties(SMDS PROPERTIES COMPILE_FLAGS "-DSMDS_EXPORTS")
set_target_properties(SMDS PROPERTIES OUTPUT_NAME "SMDS")
set_target_properties(SMDS PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set_target_properties(SMDS PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set_target_properties(SMDS PROPERTIES PREFIX "")
else(MSVC)
set_target_properties(SMDS PROPERTIES OUTPUT_NAME "SMDS")
set_target_properties(SMDS PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set_target_properties(SMDS PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set_target_properties(SMDS PROPERTIES PREFIX "")
set_target_properties(SMDS PROPERTIES INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/bin)
set_target_properties(SMDS PROPERTIES INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/lib)
endif(MSVC)
##########
@ -165,13 +165,13 @@ if(MSVC)
elseif(MINGW)
set_target_properties(Driver PROPERTIES COMPILE_FLAGS "-DMESHDRIVER_EXPORTS")
set_target_properties(Driver PROPERTIES OUTPUT_NAME "Driver")
set_target_properties(Driver PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set_target_properties(Driver PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set_target_properties(Driver PROPERTIES PREFIX "")
else(MSVC)
set_target_properties(Driver PROPERTIES OUTPUT_NAME "Driver")
set_target_properties(Driver PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set_target_properties(Driver PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set_target_properties(Driver PROPERTIES PREFIX "")
set_target_properties(Driver PROPERTIES INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/bin)
set_target_properties(Driver PROPERTIES INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/lib)
endif(MSVC)
@ -199,13 +199,13 @@ if(MSVC)
elseif(MINGW)
set_target_properties(DriverSTL PROPERTIES COMPILE_FLAGS "-DMESHDRIVERSTL_EXPORTS")
set_target_properties(DriverSTL PROPERTIES OUTPUT_NAME "DriverSTL")
set_target_properties(DriverSTL PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set_target_properties(DriverSTL PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set_target_properties(DriverSTL PROPERTIES PREFIX "")
else(MSVC)
set_target_properties(DriverSTL PROPERTIES OUTPUT_NAME "DriverSTL")
set_target_properties(DriverSTL PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set_target_properties(DriverSTL PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set_target_properties(DriverSTL PROPERTIES PREFIX "")
set_target_properties(DriverSTL PROPERTIES INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/bin)
set_target_properties(DriverSTL PROPERTIES INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/lib)
endif(MSVC)
@ -233,13 +233,13 @@ if(MSVC)
elseif(MINGW)
set_target_properties(DriverDAT PROPERTIES COMPILE_FLAGS "-DMESHDRIVERDAT_EXPORTS")
set_target_properties(DriverDAT PROPERTIES OUTPUT_NAME "DriverDAT")
set_target_properties(DriverDAT PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set_target_properties(DriverDAT PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set_target_properties(DriverDAT PROPERTIES PREFIX "")
else(MSVC)
set_target_properties(DriverDAT PROPERTIES OUTPUT_NAME "DriverDAT")
set_target_properties(DriverDAT PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set_target_properties(DriverDAT PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set_target_properties(DriverDAT PROPERTIES PREFIX "")
set_target_properties(DriverDAT PROPERTIES INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/bin)
set_target_properties(DriverDAT PROPERTIES INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/lib)
endif(MSVC)
@ -267,13 +267,13 @@ if(MSVC)
elseif(MINGW)
set_target_properties(DriverUNV PROPERTIES COMPILE_FLAGS "-DMESHDRIVERUNV_EXPORTS")
set_target_properties(DriverUNV PROPERTIES OUTPUT_NAME "DriverUNV")
set_target_properties(DriverUNV PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set_target_properties(DriverUNV PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set_target_properties(DriverUNV PROPERTIES PREFIX "")
else(MSVC)
set_target_properties(DriverUNV PROPERTIES OUTPUT_NAME "DriverUNV")
set_target_properties(DriverUNV PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set_target_properties(DriverUNV PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set_target_properties(DriverUNV PROPERTIES PREFIX "")
set_target_properties(DriverUNV PROPERTIES INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/bin)
set_target_properties(DriverUNV PROPERTIES INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/lib)
endif(MSVC)
@ -299,13 +299,13 @@ if(MSVC)
set_target_properties(SMESHDS PROPERTIES PREFIX "../")
elseif(MINGW)
set_target_properties(SMESHDS PROPERTIES OUTPUT_NAME "SMESHDS")
set_target_properties(SMESHDS PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set_target_properties(SMESHDS PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set_target_properties(SMESHDS PROPERTIES PREFIX "")
else(MSVC)
set_target_properties(SMESHDS PROPERTIES OUTPUT_NAME "SMESHDS")
set_target_properties(SMESHDS PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set_target_properties(SMESHDS PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set_target_properties(SMESHDS PROPERTIES PREFIX "")
set_target_properties(SMESHDS PROPERTIES INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/bin)
set_target_properties(SMESHDS PROPERTIES INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/lib)
endif(MSVC)
@ -330,12 +330,13 @@ if(MSVC)
elseif(MINGW)
set_target_properties(SMESH PROPERTIES COMPILE_FLAGS "-DSMESH_EXPORTS -DSMESHCONTROLS_EXPORTS -DSMESHimpl_EXPORTS")
set_target_properties(SMESH PROPERTIES OUTPUT_NAME "SMESH")
set_target_properties(SMESH PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set_target_properties(SMESH PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set_target_properties(SMESH PROPERTIES PREFIX "")
else(MSVC)
set_target_properties(SMESH PROPERTIES OUTPUT_NAME "SMESH")
set_target_properties(SMESH PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set_target_properties(SMESH PROPERTIES PREFIX "")
set_target_properties(SMESH PROPERTIES INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/bin)
set_target_properties(SMESH PROPERTIES INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/lib)
endif(MSVC)
@ -379,14 +380,15 @@ elseif(MINGW)
TARGET_LINK_LIBRARIES(MEFISTO2 ${SMESH_LIBS} gfortran)
set_target_properties(MEFISTO2 PROPERTIES COMPILE_FLAGS "-DMEFISTO2D_EXPORTS")
set_target_properties(MEFISTO2 PROPERTIES OUTPUT_NAME "MEFISTO2")
set_target_properties(MEFISTO2 PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set_target_properties(MEFISTO2 PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set_target_properties(MEFISTO2 PROPERTIES PREFIX "")
else(MSVC)
TARGET_LINK_LIBRARIES(MEFISTO2 ${SMESH_LIBS} gfortran)
set_target_properties(MEFISTO2 PROPERTIES COMPILE_FLAGS "${MEFISTO2_CFLAGS}")
set_target_properties(MEFISTO2 PROPERTIES OUTPUT_NAME "MEFISTO2")
set_target_properties(MEFISTO2 PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set_target_properties(MEFISTO2 PROPERTIES PREFIX "")
set_target_properties(MEFISTO2 PROPERTIES INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/bin)
set_target_properties(MEFISTO2 PROPERTIES INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/lib)
endif(MSVC)
@ -407,7 +409,7 @@ elseif(MINGW)
TARGET_LINK_LIBRARIES(StdMeshers SMESH ${SMESH_LIBS} MEFISTO2)
set_target_properties(StdMeshers PROPERTIES COMPILE_FLAGS "-DSTDMESHERS_EXPORTS")
set_target_properties(StdMeshers PROPERTIES OUTPUT_NAME "StdMeshers")
set_target_properties(StdMeshers PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set_target_properties(StdMeshers PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set_target_properties(StdMeshers PROPERTIES PREFIX "")
else(MSVC)
TARGET_LINK_LIBRARIES(StdMeshers SMESH ${SMESH_LIBS} MEFISTO2)
@ -419,8 +421,9 @@ else(MSVC)
ENDIF(${CMAKE_SIZEOF_VOID_P} MATCHES "8")
set_target_properties(StdMeshers PROPERTIES COMPILE_FLAGS "${StdMeshers_CFLAGS}")
set_target_properties(StdMeshers PROPERTIES OUTPUT_NAME "StdMeshers")
set_target_properties(StdMeshers PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set_target_properties(StdMeshers PROPERTIES PREFIX "")
set_target_properties(StdMeshers PROPERTIES INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/bin)
set_target_properties(StdMeshers PROPERTIES INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/lib)
endif(MSVC)
#SET(StdMeshers_CFLAGS "")
@ -450,12 +453,13 @@ if(MSVC)
elseif(MINGW)
set_target_properties(NETGENPlugin PROPERTIES COMPILE_FLAGS "-DNETGENPLUGIN_EXPORTS -DNO_PARALLEL_THREADS -DOCCGEOMETRY")
set_target_properties(NETGENPlugin PROPERTIES OUTPUT_NAME "NETGENPlugin")
set_target_properties(NETGENPlugin PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set_target_properties(NETGENPlugin PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set_target_properties(NETGENPlugin PROPERTIES PREFIX "")
else(MSVC)
set_target_properties(NETGENPlugin PROPERTIES OUTPUT_NAME "NETGENPlugin")
set_target_properties(NETGENPlugin PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set_target_properties(NETGENPlugin PROPERTIES PREFIX "")
set_target_properties(NETGENPlugin PROPERTIES INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/bin)
set_target_properties(NETGENPlugin PROPERTIES INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/lib)
endif(MSVC)
endif (FREECAD_BUILD_FEM_NETGEN)
@ -468,4 +472,27 @@ endif (FREECAD_BUILD_FEM_NETGEN)
#ENDIF(MINGW)
if(WIN32)
INSTALL(TARGETS SMDS Driver DriverSTL DriverDAT DriverUNV SMESHDS SMESH MEFISTO2 StdMeshers
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
)
else(WIN32)
INSTALL(TARGETS SMDS Driver DriverSTL DriverDAT DriverUNV SMESHDS SMESH MEFISTO2 StdMeshers
LIBRARY DESTINATION lib
)
endif(WIN32)
if (FREECAD_BUILD_FEM_NETGEN)
if(WIN32)
INSTALL(TARGETS NETGENPlugin
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
)
else(WIN32)
INSTALL(TARGETS NETGENPlugin
LIBRARY DESTINATION lib
)
endif(WIN32)
endif (FREECAD_BUILD_FEM_NETGEN)

View File

@ -1385,6 +1385,10 @@ namespace boost { namespace filesystem {
pair<string, string> 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)
@ -1493,6 +1497,9 @@ void Application::ParseOptions(int ac, char ** av)
("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 savely ignored. Mostly uses by underlaying libs.

View File

@ -229,8 +229,8 @@ bool Document::undo(void)
if (d->iUndoMode) {
if (d->activeUndoTransaction)
commitTransaction();
else
assert(mUndoTransactions.size()!=0);
else if (mUndoTransactions.empty())
return false;
// redo
d->activeUndoTransaction = new Transaction();
@ -313,12 +313,21 @@ void Document::openTransaction(const char* name)
}
}
void Document::_checkTransaction(void)
void Document::_checkTransaction(DocumentObject* pcObject)
{
// if the undo is active but no transaction open, open one!
if (d->iUndoMode) {
if (!d->activeUndoTransaction)
openTransaction();
if (!d->activeUndoTransaction) {
// When the object is going to be deleted we have to check if it has already been added to
// the undo transactions
std::list<Transaction*>::iterator it;
for (it = mUndoTransactions.begin(); it != mUndoTransactions.end(); ++it) {
if ((*it)->hasObject(pcObject)) {
openTransaction();
break;
}
}
}
}
}
@ -1440,14 +1449,14 @@ void Document::_addObject(DocumentObject* pcObject, const char* pObjectName)
/// Remove an object out of the document
void Document::remObject(const char* sName)
{
_checkTransaction();
std::map<std::string,DocumentObject*>::iterator pos = d->objectMap.find(sName);
// name not found?
if (pos == d->objectMap.end())
return;
_checkTransaction(pos->second);
if (d->activeObject == pos->second)
d->activeObject = 0;
@ -1499,7 +1508,7 @@ void Document::remObject(const char* sName)
/// Remove an object out of the document (internal)
void Document::_remObject(DocumentObject* pcObject)
{
_checkTransaction();
_checkTransaction(pcObject);
std::map<std::string,DocumentObject*>::iterator pos = d->objectMap.find(pcObject->getNameInDocument());

View File

@ -293,7 +293,7 @@ protected:
DocumentObject* _copyObject(DocumentObject* obj, std::map<DocumentObject*,
DocumentObject*>&, bool recursive=false, bool keepdigitsatend=false);
/// checks if a valid transaction is open
void _checkTransaction(void);
void _checkTransaction(DocumentObject* pcObject);
void breakDependency(DocumentObject* pcObject, bool clear);
std::vector<App::DocumentObject*> readObjects(Base::XMLReader& reader);
void writeObjects(const std::vector<App::DocumentObject*>&, Base::Writer &writer) const;

View File

@ -102,6 +102,12 @@ int Transaction::getPos(void) const
return iPos;
}
bool Transaction::hasObject(DocumentObject *Obj) const
{
std::map<const DocumentObject*,TransactionObject*>::const_iterator it;
it = _Objects.find(Obj);
return (it != _Objects.end());
}
//**************************************************************************
// separator for other implemetation aspects

View File

@ -93,6 +93,8 @@ public:
/// get the position in the transaction history
int getPos(void) const;
/// check if this object is used in a transaction
bool hasObject(DocumentObject *Obj) const;
friend class Document;

View File

@ -14,6 +14,7 @@ include_directories(
${XERCESC_INCLUDE_DIR}
${QT_QTCORE_INCLUDE_DIR}
${ZLIB_INCLUDE_DIR}
${PYCXX_INCLUDE_DIR}
)
if(MSVC)
@ -62,6 +63,8 @@ generate_from_xml(MatrixPy)
generate_from_xml(RotationPy)
generate_from_xml(PlacementPy)
generate_from_xml(AxisPy)
generate_from_xml(UnitPy)
generate_from_xml(QuantityPy)
if(SWIG_FOUND)
execute_process(COMMAND ${SWIG_EXECUTABLE} -python -external-runtime ${CMAKE_CURRENT_BINARY_DIR}/swigpyrun.h)
@ -124,20 +127,7 @@ SET(zipios_SRCS
SOURCE_GROUP("zipios" FILES ${zipios_SRCS})
endif ()
SET(pycxx_SRCS
../CXX/Config.hxx
../CXX/cxxextensions.c
../CXX/cxx_extensions.cxx
../CXX/cxxsupport.cxx
../CXX/Exception.hxx
../CXX/Extensions.hxx
../CXX/IndirectPythonInterface.cxx
../CXX/IndirectPythonInterface.hxx
../CXX/Objects.hxx
../CXX/Version.hxx
../CXX/WrapPython.h
)
SOURCE_GROUP("pycxx" FILES ${pycxx_SRCS})
SOURCE_GROUP("pycxx" FILES ${PYCXX_SOURCES})
SET(FreeCADBase_XML_SRCS
AxisPy.xml
@ -148,6 +138,8 @@ SET(FreeCADBase_XML_SRCS
PlacementPy.xml
RotationPy.xml
VectorPy.xml
QuantityPy.xml
UnitPy.xml
)
SOURCE_GROUP("XML" FILES ${FreeCADBase_XML_SRCS})
@ -171,6 +163,15 @@ SET(FreeCADBase_UNITAPI_SRCS
UnitsSchemaImperial1.cpp
UnitsApi.y
UnitsApi.l
Quantity.h
Quantity.cpp
QuantityPyImp.cpp
QuantityParser.l
QuantityParser.y
Unit.h
Unit.cpp
UnitPyImp.cpp
)
SOURCE_GROUP("Units" FILES ${FreeCADBase_UNITAPI_SRCS})
@ -279,7 +280,7 @@ SET(FreeCADBase_HPP_SRCS
)
SET(FreeCADBase_SRCS
${pycxx_SRCS}
${PYCXX_SOURCES}
${FreeCADBase_CPP_SRCS}
${FreeCADBase_HPP_SRCS}
${FreeCADBase_XML_SRCS}

View File

@ -133,6 +133,28 @@ ConsoleMsgFlags ConsoleSingleton::SetEnabledMsgType(const char* sObs, ConsoleMsg
}
}
bool ConsoleSingleton::IsMsgTypeEnabled(const char* sObs, FreeCAD_ConsoleMsgType type) const
{
ConsoleObserver* pObs = Get(sObs);
if (pObs) {
switch (type) {
case MsgType_Txt:
return pObs->bMsg;
case MsgType_Log:
return pObs->bLog;
case MsgType_Wrn:
return pObs->bWrn;
case MsgType_Err:
return pObs->bErr;
default:
return false;
}
}
else {
return false;
}
}
/** Prints a Message
* This method issues a Message.
* Messages are used show some non vital information. That means in the
@ -207,7 +229,7 @@ void ConsoleSingleton::Error( const char *pMsg, ... )
/** Prints a Message
* this method is more for devlopment and tracking purpos.
* It can be used to track execution of algorithems and functions
* It can be used to track execution of algorithms and functions
* and put it in files. The normal user dont need to see it, its more
* for developers and experinced users. So in normal user modes the
* logging is switched of.
@ -282,37 +304,40 @@ void ConsoleSingleton::DetachObserver(ConsoleObserver *pcObserver)
void ConsoleSingleton::NotifyMessage(const char *sMsg)
{
for(std::set<ConsoleObserver * >::iterator Iter=_aclObservers.begin();Iter!=_aclObservers.end();Iter++)
for(std::set<ConsoleObserver * >::iterator Iter=_aclObservers.begin();Iter!=_aclObservers.end();Iter++) {
if((*Iter)->bMsg)
(*Iter)->Message(sMsg); // send string to the listener
}
}
void ConsoleSingleton::NotifyWarning(const char *sMsg)
{
for(std::set<ConsoleObserver * >::iterator Iter=_aclObservers.begin();Iter!=_aclObservers.end();Iter++)
for(std::set<ConsoleObserver * >::iterator Iter=_aclObservers.begin();Iter!=_aclObservers.end();Iter++) {
if((*Iter)->bWrn)
(*Iter)->Warning(sMsg); // send string to the listener
}
}
void ConsoleSingleton::NotifyError(const char *sMsg)
{
for(std::set<ConsoleObserver * >::iterator Iter=_aclObservers.begin();Iter!=_aclObservers.end();Iter++)
for(std::set<ConsoleObserver * >::iterator Iter=_aclObservers.begin();Iter!=_aclObservers.end();Iter++) {
if((*Iter)->bErr)
(*Iter)->Error(sMsg); // send string to the listener
}
}
void ConsoleSingleton::NotifyLog(const char *sMsg)
{
for(std::set<ConsoleObserver * >::iterator Iter=_aclObservers.begin();Iter!=_aclObservers.end();Iter++)
for(std::set<ConsoleObserver * >::iterator Iter=_aclObservers.begin();Iter!=_aclObservers.end();Iter++) {
if((*Iter)->bLog)
(*Iter)->Log(sMsg); // send string to the listener
}
}
ConsoleObserver *ConsoleSingleton::Get(const char *Name)
ConsoleObserver *ConsoleSingleton::Get(const char *Name) const
{
const char* OName;
for(std::set<ConsoleObserver * >::iterator Iter=_aclObservers.begin();Iter!=_aclObservers.end();Iter++)
{
for(std::set<ConsoleObserver * >::const_iterator Iter=_aclObservers.begin();Iter!=_aclObservers.end();Iter++) {
OName = (*Iter)->Name(); // get the name
if(OName && strcmp(OName,Name) == 0)
return *Iter;
@ -539,13 +564,13 @@ PyObject *ConsoleSingleton::sPySetStatus(PyObject * /*self*/, PyObject *args, Py
if(pObs)
{
if(strcmp(pstr2,"Log") == 0)
pObs->bLog = (Bool==0)?false:true;
pObs->bLog = (Bool==0)?false:true;
else if(strcmp(pstr2,"Wrn") == 0)
pObs->bWrn = (Bool==0)?false:true;
pObs->bWrn = (Bool==0)?false:true;
else if(strcmp(pstr2,"Msg") == 0)
pObs->bMsg = (Bool==0)?false:true;
pObs->bMsg = (Bool==0)?false:true;
else if(strcmp(pstr2,"Err") == 0)
pObs->bErr = (Bool==0)?false:true;
pObs->bErr = (Bool==0)?false:true;
else
Py_Error(PyExc_Exception,"Unknown Message Type (use Log,Err,Msg or Wrn)");

View File

@ -56,7 +56,7 @@ class ConsoleSingleton;
typedef Base::ConsoleSingleton ConsoleMsgType;
typedef unsigned int ConsoleMsgFlags;
namespace Base {
/** The console observer class
@ -141,12 +141,14 @@ public:
void UnsetMode(ConsoleMode m);
/// Enables or disables message types of a cetain console observer
ConsoleMsgFlags SetEnabledMsgType(const char* sObs, ConsoleMsgFlags type, bool b);
/// Enables or disables message types of a cetain console observer
bool IsMsgTypeEnabled(const char* sObs, FreeCAD_ConsoleMsgType type) const;
/// singleton
static ConsoleSingleton &Instance(void);
// retrieval of an observer by name
ConsoleObserver *Get(const char *Name);
ConsoleObserver *Get(const char *Name) const;
static PyMethodDef Methods[];

View File

@ -71,12 +71,16 @@ PyException::PyException(void)
_stackTrace = PP_last_error_trace; /* exception traceback text */
// This should be done in the constructor because when doing
// in the destructor it's not always clear when it is called
// and thus may clear a Python exception when it should not.
PyGILStateLocker locker;
PyErr_Clear(); // must be called to keep Python interpreter in a valid state (Werner)
}
PyException::~PyException() throw()
{
PyGILStateLocker locker;
PyErr_Clear(); // must be called to keep Python interpreter in a valid state (Werner)
}
void PyException::ReportException (void) const

View File

@ -23,8 +23,8 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <memory>
# include <cstring>
# include <memory>
# include <cstring>
# include <sstream>
#endif
@ -80,6 +80,14 @@ void Matrix4D::setToUnity (void)
dMtrx4D[3][0] = 0.0; dMtrx4D[3][1] = 0.0; dMtrx4D[3][2] = 0.0; dMtrx4D[3][3] = 1.0;
}
void Matrix4D::nullify(void)
{
dMtrx4D[0][0] = 0.0; dMtrx4D[0][1] = 0.0; dMtrx4D[0][2] = 0.0; dMtrx4D[0][3] = 0.0;
dMtrx4D[1][0] = 0.0; dMtrx4D[1][1] = 0.0; dMtrx4D[1][2] = 0.0; dMtrx4D[1][3] = 0.0;
dMtrx4D[2][0] = 0.0; dMtrx4D[2][1] = 0.0; dMtrx4D[2][2] = 0.0; dMtrx4D[2][3] = 0.0;
dMtrx4D[3][0] = 0.0; dMtrx4D[3][1] = 0.0; dMtrx4D[3][2] = 0.0; dMtrx4D[3][3] = 0.0;
}
double Matrix4D::determinant() const
{
double fA0 = dMtrx4D[0][0]*dMtrx4D[1][1] - dMtrx4D[0][1]*dMtrx4D[1][0];
@ -701,8 +709,8 @@ void Matrix4D::fromString(const std::string &str)
input >> dMtrx4D[i][j];
}
}
// Analyse the a transformation Matrix and describe the transformation
// Analyse the a transformation Matrix and describe the transformation
std::string Matrix4D::analyse(void) const
{
const double eps=1.0e-06;
@ -723,22 +731,22 @@ std::string Matrix4D::analyse(void) const
}
else //translation and affine
{
if (dMtrx4D[0][1] == 0.0 && dMtrx4D[0][2] == 0.0 &&
dMtrx4D[1][0] == 0.0 && dMtrx4D[1][2] == 0.0 &&
if (dMtrx4D[0][1] == 0.0 && dMtrx4D[0][2] == 0.0 &&
dMtrx4D[1][0] == 0.0 && dMtrx4D[1][2] == 0.0 &&
dMtrx4D[2][0] == 0.0 && dMtrx4D[2][1] == 0.0) //scaling
{
std::ostringstream stringStream;
stringStream << "Scale [" << dMtrx4D[0][0] << ", " <<
std::ostringstream stringStream;
stringStream << "Scale [" << dMtrx4D[0][0] << ", " <<
dMtrx4D[1][1] << ", " << dMtrx4D[2][2] << "]";
text = stringStream.str();
text = stringStream.str();
}
else
{
Base::Matrix4D sub;
sub[0][0] = dMtrx4D[0][0]; sub[0][1] = dMtrx4D[0][1];
sub[0][2] = dMtrx4D[0][2]; sub[1][0] = dMtrx4D[1][0];
sub[0][0] = dMtrx4D[0][0]; sub[0][1] = dMtrx4D[0][1];
sub[0][2] = dMtrx4D[0][2]; sub[1][0] = dMtrx4D[1][0];
sub[1][1] = dMtrx4D[1][1]; sub[1][2] = dMtrx4D[1][2];
sub[2][0] = dMtrx4D[2][0]; sub[2][1] = dMtrx4D[2][1];
sub[2][0] = dMtrx4D[2][0]; sub[2][1] = dMtrx4D[2][1];
sub[2][2] = dMtrx4D[2][2];
Base::Matrix4D trp = sub;
@ -771,23 +779,23 @@ std::string Matrix4D::analyse(void) const
}
else //scaling with rotation
{
std::ostringstream stringStream;
stringStream << "Scale and Rotate ";
std::ostringstream stringStream;
stringStream << "Scale and Rotate ";
if (determinant<0.0 )
stringStream << "and Invert ";
stringStream << "[ " <<
sqrt(trp[0][0]) << ", " << sqrt(trp[1][1]) << ", " <<
stringStream << "and Invert ";
stringStream << "[ " <<
sqrt(trp[0][0]) << ", " << sqrt(trp[1][1]) << ", " <<
sqrt(trp[2][2]) << "]";
text = stringStream.str();
text = stringStream.str();
}
}
}
else
{
std::ostringstream stringStream;
stringStream << "Affine with det= " <<
std::ostringstream stringStream;
stringStream << "Affine with det= " <<
determinant;
text = stringStream.str();
text = stringStream.str();
}
}
}
@ -795,4 +803,4 @@ std::string Matrix4D::analyse(void) const
text += " with Translation";
}
return text;
}
}

View File

@ -26,7 +26,7 @@
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdio>
#include <string>
#include "Vector3D.h"
@ -104,7 +104,9 @@ public:
/** @name Manipulation */
//@{
/// Makes unity matrix
void setToUnity (void);
void setToUnity(void);
/// Makes a null matrix
void nullify(void);
/// moves the coordinatesystem for the x,y,z value
void move (float x, float y, float z)
{ move(Vector3f(x,y,z)); }

2
src/Base/Parser.bat Normal file
View File

@ -0,0 +1,2 @@
C:\Tools\GnuWin32\bin\flex.exe -oQuantityLexer.c QuantityParser.l
C:\Tools\GnuWin32\bin\bison -oQuantityParser.c QuantityParser.y

157
src/Base/Quantity.cpp Normal file
View File

@ -0,0 +1,157 @@
/***************************************************************************
* Copyright (c) 2013 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 <cmath>
#include "Quantity.h"
#include "Exception.h"
using namespace Base;
Quantity::Quantity()
{
this->_Value = 0.0;
}
Quantity::Quantity(const Quantity& that)
{
*this = that ;
}
Quantity::Quantity(double Value, const Unit& unit)
{
this->_Unit = unit;
this->_Value = Value;
}
bool Quantity::operator ==(const Quantity& that) const
{
return (this->_Value == that._Value) && (this->_Unit == that._Unit) ;
}
Quantity Quantity::operator *(const Quantity &p) const
{
return Quantity(this->_Value * p._Value,this->_Unit * p._Unit);
}
Quantity Quantity::operator /(const Quantity &p) const
{
return Quantity(this->_Value / p._Value,this->_Unit / p._Unit);
}
Quantity Quantity::pow(const Quantity &p) const
{
if(!p._Unit.isEmpty())
throw Base::Exception("Quantity::pow(): exponent must not have a unit");
return Quantity(
std::pow(this->_Value, p._Value),
this->_Unit.pow((short)p._Value)
);
}
Quantity Quantity::operator +(const Quantity &p) const
{
if(this->_Unit != p._Unit)
throw Base::Exception("Quantity::operator +(): Unit missmatch in plus operation");
return Quantity(this->_Value + p._Value,this->_Unit);
}
Quantity Quantity::operator -(const Quantity &p) const
{
if(this->_Unit != p._Unit)
throw Base::Exception("Quantity::operator +(): Unit missmatch in plus operation");
return Quantity(this->_Value - p._Value,this->_Unit);
}
Quantity Quantity::operator -(void) const
{
return Quantity(-(this->_Value),this->_Unit);
}
Quantity& Quantity::operator = (const Quantity &New)
{
this->_Value = New._Value;
this->_Unit = New._Unit;
return *this;
}
// === Parser & Scanner stuff ===============================================
// include the Scanner and the Parser for the Quantitys
Quantity QuantResult;
#ifndef DOUBLE_MAX
# define DOUBLE_MAX 1.7976931348623157E+308 /* max decimal value of a "double"*/
#endif
#ifndef DOUBLE_MIN
# define DOUBLE_MIN 2.2250738585072014E-308 /* min decimal value of a "double"*/
#endif
// error func
void Quantity_yyerror(char *errorinfo)
{
throw Base::Exception(errorinfo);
}
// for VC9 (isatty and fileno not supported anymore)
//#ifdef _MSC_VER
//int isatty (int i) {return _isatty(i);}
//int fileno(FILE *stream) {return _fileno(stream);}
//#endif
namespace QuantityParser {
// show the parser the lexer method
#define yylex QuantityLexer
int QuantityLexer(void);
// Parser, defined in QuantityParser.y
#include "QuantityParser.c"
#ifndef DOXYGEN_SHOULD_SKIP_THIS
// Scanner, defined in QuantityParser.l
#include "QuantityLexer.c"
#endif // DOXYGEN_SHOULD_SKIP_THIS
}
Quantity Quantity::parse(const char* buffer)
{
// parse from buffer
QuantityParser::YY_BUFFER_STATE my_string_buffer = QuantityParser::yy_scan_string (buffer);
// set the global return variables
QuantResult = Quantity(DOUBLE_MIN);
// run the parser
QuantityParser::yyparse ();
// free the scan buffer
QuantityParser::yy_delete_buffer (my_string_buffer);
if (QuantResult == Quantity(DOUBLE_MIN))
throw Base::Exception("Unknown error in Quantity expression");
return QuantResult;
}

65
src/Base/Quantity.h Normal file
View File

@ -0,0 +1,65 @@
/***************************************************************************
* Copyright (c) 2013 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 BASE_Quantity_H
#define BASE_Quantity_H
#include "Unit.h"
namespace Base {
/**
* The Quantity class.
*/
class BaseExport Quantity
{
public:
/// default constructor
Quantity(void);
Quantity(const Quantity&);
Quantity(double Value, const Unit& unit=Unit());
/// Destruction
~Quantity () {};
/** Operators. */
//@{
Quantity operator *(const Quantity &p) const;
Quantity operator +(const Quantity &p) const;
Quantity operator -(const Quantity &p) const;
Quantity operator -(void) const;
Quantity operator /(const Quantity &p) const;
bool operator ==(const Quantity&) const;
Quantity& operator =(const Quantity&);
Quantity pow(const Quantity&)const;
//@}
protected:
double _Value;
Unit _Unit;
static Quantity parse(const char* buffer);
};
} // namespace Base
#endif // BASE_Quantity_H

1743
src/Base/QuantityLexer.c Normal file

File diff suppressed because it is too large Load Diff

1615
src/Base/QuantityParser.c Normal file

File diff suppressed because it is too large Load Diff

85
src/Base/QuantityParser.l Normal file
View File

@ -0,0 +1,85 @@
%{
/* Lexer for the FreeCAD Units language */
/* (c) 2013 Juergen Riegel LGPL */
/* This disables inclusion of unistd.h, which is not available under Visual C++
* on Win32. The C++ scanner uses STL streams instead. */
#define YY_NO_UNISTD_H
%}
/*** Flex Declarations and Options ***/
/* the manual says "somewhat more optimized" */
%option batch
%option never-interactive
/* no support for include files is planned */
%option noyywrap nounput
DIGIT [0-9]
ID [a-z][a-z0-9]*
%% /*** Filter language Part ***/
[ \t] ;
[\n]+ ;
[-+()=/*^] { return *yytext; }
"mm" yylval = 1.0; return UNIT; // millimeter (internal standard length)
"m" yylval = 1000.0; return UNIT; // meter
"cm" yylval = 10.0; return UNIT; // centimeter
"dm" yylval = 100.0; return UNIT; // decimeter
"km" yylval = 1000000.0; return UNIT; // kilometer
"in" yylval = 25.4; return UNIT; // inch
"\"" yylval = 25.4; return UNIT; // inch
"fo" yylval = 304.8; return UNIT; // foot
"'" yylval = 304.8; return UNIT; // foot
"th" yylval = 0.0254; return UNIT; // thou
"yr" yylval = 914.4; return UNIT; // yard
"kg" yylval = 1.0; return UNIT; // kilogram (internal standard mass)
"g" yylval = 0.001; return UNIT; // gram
"mg" yylval = 0.000001; return UNIT; // milligram
"t" yylval = 1000.0; return UNIT; // ton
"lb" yylval = 0.45359237; return UNIT; // pound
"oz" yylval = 0.45359237; return UNIT; // ounce
"st" yylval = 6.35029318; return UNIT; // Stone
"cwt" yylval = 50.80234544;return UNIT; // hundredweights
"deg" yylval = 1.0; return UNIT; // degree (internal standard angle)
"rad" yylval = 180/M_PI; return UNIT; // radian
"gon" yylval = 360.0/400.0;return UNIT; // gon
"s" yylval = 1.0; return UNIT; // second (internal standard time)
"min" yylval = 60.0; return UNIT; // minute
"h" yylval = 3600.0; return UNIT; // hour
"A" yylval = 1.0; return UNIT; // Ampere (internal standard electric current)
"K" yylval = 1.0; return UNIT; // Kelvin (internal standard thermodynamic temperature)
"cd" yylval = 1.0; return UNIT; // Candela (internal standard luminous intensity)
"mol" yylval = 1.0; return UNIT; // Mole (internal standard amount of substance)
"yl" yylval = 1.0; return UNIT; // microliter mm^3(derived standard volume)
"ml" yylval = 1000.0; return UNIT; // milliliter cm^3
"l" yylval = 1000000.0; return UNIT; // Liter dm^3
{DIGIT}+"."{DIGIT}* {yylval = atof( yytext ); return NUM;}
{DIGIT}+ {yylval = atof( yytext ); return NUM;}
"pi" {yylval = M_PI ; return NUM;} // constant pi
"e" {yylval = M_E ; return NUM;} // constant e

41
src/Base/QuantityParser.y Normal file
View File

@ -0,0 +1,41 @@
/* Parser for the FreeCAD Units language */
/* (c) 2013 Juergen Riegel LGPL */
/* Represents the many different ways we can access our data */
%{
#define YYSTYPE Quantity
#define yyparse Quantity_yyparse
#define yyerror Quantity_yyerror
%}
/* Bison declarations. */
%token UNIT NUM
%left '-' '+'
%left '*' '/'
%left NEG /* negation--unary minus */
%right '^' /* exponentiation */
%start input
%%
input: exp { QuantResult = $1 ; }
;
exp: NUM { $$ = $1; }
| UNIT { $$ = $1; }
| NUM UNIT { $$ = $1*$2; }
| exp '+' exp { $$ = $1 + $3; }
| exp '-' exp { $$ = $1 - $3; }
| exp '*' exp { $$ = $1 * $3; }
| exp '/' exp { $$ = $1 / $3; }
| '-' exp %prec NEG { $$ = -$2; }
| exp '^' NUM { $$ = $1.pow($3); }
| '(' exp ')' { $$ = $2; }
;
%%

48
src/Base/QuantityPy.xml Normal file
View File

@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8"?>
<GenerateModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="generateMetaModel_Module.xsd">
<PythonExport
Father="PyObjectBase"
Name="QuantityPy"
Twin="Quantity"
TwinPointer="Quantity"
Include="Base/Quantity.h"
FatherInclude="Base/PyObjectBase.h"
Namespace="Base"
Constructor="true"
Delete="true"
FatherNamespace="Base">
<Documentation>
<Author Licence="LGPL" Name="Juergen Riegel" EMail="FreeCAD@juergen-riegel.net" />
<UserDocu>Quantity
defined by a value and a unit.
The following constructors are supported:
Quantity() -- empty constructor
Quantity(Value) -- empty constructor
Quantity(Value,Unit) -- empty constructor
Quantity(Quantity) -- copy constructor
Quantity(string) -- arbitrary mixture of numbers and chars defining a Quantity
</UserDocu>
<DeveloperDocu>Quantity</DeveloperDocu>
</Documentation>
<Methode Name="multiply">
<Documentation>
<UserDocu>
multiply two quantities
</UserDocu>
</Documentation>
</Methode>
<Attribute Name="Value" ReadOnly="false">
<Documentation>
<UserDocu>Vector to the Base position of the Quantity</UserDocu>
</Documentation>
<Parameter Name="Value" Type="Float" />
</Attribute>
<Attribute Name="Unit" ReadOnly="false">
<Documentation>
<UserDocu>Direction vector of the Quantity</UserDocu>
</Documentation>
<Parameter Name="Unit" Type="Object" />
</Attribute>
</PythonExport>
</GenerateModel>

View File

@ -0,0 +1,73 @@
#include "PreCompiled.h"
#include "Base/Quantity.h"
// inclusion of the generated files (generated out of QuantityPy.xml)
#include "QuantityPy.h"
#include "QuantityPy.cpp"
using namespace Base;
// returns a string which represents the object e.g. when printed in python
std::string QuantityPy::representation(void) const
{
return std::string("<Quantity object>");
}
PyObject *QuantityPy::PyMake(struct _typeobject *, PyObject *, PyObject *) // Python wrapper
{
// create a new instance of QuantityPy and the Twin object
return new QuantityPy(new Quantity);
}
// constructor method
int QuantityPy::PyInit(PyObject* /*args*/, PyObject* /*kwd*/)
{
return 0;
}
PyObject* QuantityPy::multiply(PyObject * /*args*/)
{
PyErr_SetString(PyExc_NotImplementedError, "Not yet implemented");
return 0;
}
Py::Float QuantityPy::getValue(void) const
{
//return Py::Float();
throw Py::AttributeError("Not yet implemented");
}
void QuantityPy::setValue(Py::Float /*arg*/)
{
throw Py::AttributeError("Not yet implemented");
}
Py::Object QuantityPy::getUnit(void) const
{
//return Py::Object();
throw Py::AttributeError("Not yet implemented");
}
void QuantityPy::setUnit(Py::Object /*arg*/)
{
throw Py::AttributeError("Not yet implemented");
}
PyObject *QuantityPy::getCustomAttributes(const char* /*attr*/) const
{
return 0;
}
int QuantityPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/)
{
return 0;
}

151
src/Base/Unit.cpp Normal file
View File

@ -0,0 +1,151 @@
/***************************************************************************
* 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 "Unit.h"
using namespace Base;
Unit::Unit(int8_t Length,
int8_t Mass,
int8_t Time,
int8_t ElectricCurrent,
int8_t ThermodynamicTemperature,
int8_t AmountOfSubstance,
int8_t LuminoseIntensity,
int8_t Angle)
{
Sig.Length = Length;
Sig.Mass = Mass;
Sig.Time = Time;
Sig.ElectricCurrent = ElectricCurrent;
Sig.ThermodynamicTemperature = ThermodynamicTemperature;
Sig.AmountOfSubstance = AmountOfSubstance;
Sig.LuminoseIntensity = LuminoseIntensity;
Sig.Angle = Angle;
}
Unit::Unit()
{
}
Unit::Unit(const Unit& that)
{
this->Sig = that.Sig;
}
Unit::Unit(const std::string& Pars)
{
}
Unit Unit::pow(char exp)const
{
Unit result;
result.Sig.Length = Sig.Length * exp;
result.Sig.Mass = Sig.Mass * exp;
result.Sig.Time = Sig.Time * exp;
result.Sig.ElectricCurrent = Sig.ElectricCurrent * exp;
result.Sig.ThermodynamicTemperature = Sig.ThermodynamicTemperature * exp;
result.Sig.AmountOfSubstance = Sig.AmountOfSubstance * exp;
result.Sig.LuminoseIntensity = Sig.LuminoseIntensity * exp;
result.Sig.Angle = Sig.Angle * exp;
return result;
}
bool Unit::isEmpty(void)const
{
return (this->Sig.Length == 0)
&& (this->Sig.Mass == 0)
&& (this->Sig.Time == 0)
&& (this->Sig.ElectricCurrent == 0)
&& (this->Sig.ThermodynamicTemperature == 0)
&& (this->Sig.AmountOfSubstance == 0)
&& (this->Sig.LuminoseIntensity == 0)
&& (this->Sig.Angle == 0);
}
bool Unit::operator ==(const Unit& that) const
{
return (this->Sig.Length == that.Sig.Length)
&& (this->Sig.Mass == that.Sig.Mass)
&& (this->Sig.Time == that.Sig.Time)
&& (this->Sig.ElectricCurrent == that.Sig.ElectricCurrent)
&& (this->Sig.ThermodynamicTemperature == that.Sig.ThermodynamicTemperature)
&& (this->Sig.AmountOfSubstance == that.Sig.AmountOfSubstance)
&& (this->Sig.LuminoseIntensity == that.Sig.LuminoseIntensity)
&& (this->Sig.Angle == that.Sig.Angle);
}
Unit Unit::operator *(const Unit &right) const
{
Unit result;
result.Sig.Length = Sig.Length + right.Sig.Length;
result.Sig.Mass = Sig.Mass + right.Sig.Mass;
result.Sig.Time = Sig.Time + right.Sig.Time;
result.Sig.ElectricCurrent = Sig.ElectricCurrent + right.Sig.ElectricCurrent;
result.Sig.ThermodynamicTemperature = Sig.ThermodynamicTemperature + right.Sig.ThermodynamicTemperature;
result.Sig.AmountOfSubstance = Sig.AmountOfSubstance + right.Sig.AmountOfSubstance;
result.Sig.LuminoseIntensity = Sig.LuminoseIntensity + right.Sig.LuminoseIntensity;
result.Sig.Angle = Sig.Angle + right.Sig.Angle;
return result;
}
Unit Unit::operator /(const Unit &right) const
{
Unit result;
result.Sig.Length = Sig.Length - right.Sig.Length;
result.Sig.Mass = Sig.Mass - right.Sig.Mass;
result.Sig.Time = Sig.Time - right.Sig.Time;
result.Sig.ElectricCurrent = Sig.ElectricCurrent - right.Sig.ElectricCurrent;
result.Sig.ThermodynamicTemperature = Sig.ThermodynamicTemperature - right.Sig.ThermodynamicTemperature;
result.Sig.AmountOfSubstance = Sig.AmountOfSubstance - right.Sig.AmountOfSubstance;
result.Sig.LuminoseIntensity = Sig.LuminoseIntensity - right.Sig.LuminoseIntensity;
result.Sig.Angle = Sig.Angle - right.Sig.Angle;
return result;
}
Unit& Unit::operator = (const Unit &New)
{
Sig.Length = New.Sig.Length;
Sig.Mass = New.Sig.Mass ;
Sig.Time = New.Sig.Time ;
Sig.ElectricCurrent = New.Sig.ElectricCurrent ;
Sig.ThermodynamicTemperature = New.Sig.ThermodynamicTemperature;
Sig.AmountOfSubstance = New.Sig.AmountOfSubstance ;
Sig.LuminoseIntensity = New.Sig.LuminoseIntensity ;
Sig.Angle = New.Sig.Angle ;
return *this;
}

95
src/Base/Unit.h Normal file
View File

@ -0,0 +1,95 @@
/***************************************************************************
* 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 BASE_Unit_H
#define BASE_Unit_H
#ifdef _MSC_VER
# include <boost/cstdint.hpp>
#else
# include <stdint.h>
#endif
#include <string>
namespace Base {
struct UnitSignature{
int32_t Length:4;
int32_t Mass:4;
int32_t Time:4;
int32_t ElectricCurrent:4;
int32_t ThermodynamicTemperature:4;
int32_t AmountOfSubstance:4;
int32_t LuminoseIntensity:4;
int32_t Angle:4;
};
/**
* The Unit class.
*/
class BaseExport Unit
{
public:
/// default constructor
Unit(int8_t Length,int8_t Mass=0,int8_t Time=0,int8_t ElectricCurrent=0,int8_t ThermodynamicTemperature=0,int8_t AmountOfSubstance=0,int8_t LuminoseIntensity=0,int8_t Angle=0);
Unit(void);
Unit(const Unit&);
Unit(const std::string& Pars);
/// Destruction
~Unit () {};
/** Operators. */
//@{
inline Unit& operator *=(const Unit& that);
inline Unit& operator /=(const Unit& that);
Unit operator *(const Unit&) const;
Unit operator /(const Unit&) const;
bool operator ==(const Unit&) const;
bool operator !=(const Unit&that) const {return !(*this == that);}
Unit& operator =(const Unit&);
Unit pow(char exp)const;
//@}
bool isEmpty(void)const;
char getLengthDimension(void){return Sig.Length;}
protected:
UnitSignature Sig;
};
inline Unit& Unit::operator *=(const Unit& that)
{
*this = *this * that;
return *this;
}
inline Unit& Unit::operator /=(const Unit& that)
{
*this = *this / that;
return *this;
}
} // namespace Base
#endif // BASE_Unit_H

48
src/Base/UnitPy.xml Normal file
View File

@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8"?>
<GenerateModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="generateMetaModel_Module.xsd">
<PythonExport
Father="PyObjectBase"
Name="UnitPy"
Twin="Unit"
TwinPointer="Unit"
Include="Base/Unit.h"
FatherInclude="Base/PyObjectBase.h"
Namespace="Base"
Constructor="true"
Delete="true"
FatherNamespace="Base">
<Documentation>
<Author Licence="LGPL" Name="Juergen Riegel" EMail="FreeCAD@juergen-riegel.net" />
<UserDocu>Unit
defines a unit type and calculate and compare.
The following constructors are supported:
Unit() -- empty constructor
Unit(Unit) -- copy constructor
Unit(string) -- parse the string for units
</UserDocu>
<DeveloperDocu>Unit</DeveloperDocu>
</Documentation>
<Methode Name="multiply">
<Documentation>
<UserDocu>
multiply(Placement)
Multiply this axis with a placement
</UserDocu>
</Documentation>
</Methode>
<Methode Name="getType">
<Documentation>
<UserDocu>
get the type of the unit as string
</UserDocu>
</Documentation>
</Methode>
<Attribute Name="Dimensions" ReadOnly="false">
<Documentation>
<UserDocu>get the dimension as a vector with 8 fields</UserDocu>
</Documentation>
<Parameter Name="Direction" Type="Object" />
</Attribute>
</PythonExport>
</GenerateModel>

68
src/Base/UnitPyImp.cpp Normal file
View File

@ -0,0 +1,68 @@
#include "PreCompiled.h"
#include "Base/Unit.h"
// inclusion of the generated files (generated out of UnitPy.xml)
#include "UnitPy.h"
#include "UnitPy.cpp"
using namespace Base;
// returns a string which represents the object e.g. when printed in python
std::string UnitPy::representation(void) const
{
return std::string("<Unit object>");
}
PyObject *UnitPy::PyMake(struct _typeobject *, PyObject *, PyObject *) // Python wrapper
{
// create a new instance of UnitPy and the Twin object
return new UnitPy(new Unit);
}
// constructor method
int UnitPy::PyInit(PyObject* /*args*/, PyObject* /*kwd*/)
{
return 0;
}
PyObject* UnitPy::multiply(PyObject * /*args*/)
{
PyErr_SetString(PyExc_NotImplementedError, "Not yet implemented");
return 0;
}
PyObject* UnitPy::getType(PyObject * /*args*/)
{
PyErr_SetString(PyExc_NotImplementedError, "Not yet implemented");
return 0;
}
Py::Object UnitPy::getDimensions(void) const
{
//return Py::Object();
throw Py::AttributeError("Not yet implemented");
}
void UnitPy::setDimensions(Py::Object /*arg*/)
{
throw Py::AttributeError("Not yet implemented");
}
PyObject *UnitPy::getCustomAttributes(const char* /*attr*/) const
{
return 0;
}
int UnitPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/)
{
return 0;
}

View File

@ -32,6 +32,13 @@
</UserDocu>
</Documentation>
</Methode>
<Methode Name="negative" Const="true">
<Documentation>
<UserDocu>negative()
returns the negative (opposite) of this vector
</UserDocu>
</Documentation>
</Methode>
<Methode Name="scale">
<Documentation>
<UserDocu>scale(Float,Float,Float)
@ -88,6 +95,14 @@
</UserDocu>
</Documentation>
</Methode>
<Methode Name="distanceToPoint" Const="true">
<Documentation>
<UserDocu>
distanceToPoint(Vector)
returns the distance to another point
</UserDocu>
</Documentation>
</Methode>
<Methode Name="distanceToLine" Const="true">
<Documentation>
<UserDocu>distanceToLine(Vector,Vector)

View File

@ -215,6 +215,16 @@ PyObject* VectorPy::sub(PyObject *args)
return new VectorPy(v);
}
PyObject* VectorPy::negative(PyObject *args)
{
if (!PyArg_ParseTuple(args, ""))
return 0;
VectorPy::PointerType this_ptr = reinterpret_cast<VectorPy::PointerType>(_pcTwinPointer);
Base::Vector3d v = -(*this_ptr);
return new VectorPy(v);
}
PyObject* VectorPy::richCompare(PyObject *v, PyObject *w, int op)
{
if (PyObject_TypeCheck(v, &(VectorPy::Type)) &&
@ -380,6 +390,20 @@ PyObject* VectorPy::projectToPlane(PyObject *args)
return Py::new_reference_to(this);
}
PyObject* VectorPy::distanceToPoint(PyObject *args)
{
PyObject *pnt;
if (!PyArg_ParseTuple(args, "O!",&(VectorPy::Type),&pnt))
return 0;
VectorPy* base_vec = static_cast<VectorPy*>(pnt);
VectorPy::PointerType this_ptr = reinterpret_cast<VectorPy::PointerType>(_pcTwinPointer);
VectorPy::PointerType base_ptr = reinterpret_cast<VectorPy::PointerType>(base_vec->_pcTwinPointer);
Py::Float dist(Base::Distance(*this_ptr, *base_ptr));
return Py::new_reference_to(dist);
}
PyObject* VectorPy::distanceToLine(PyObject *args)
{
PyObject *base, *line;

View File

@ -1,9 +1,12 @@
The FreeCAD Document
====================
.. currentmodule:: FreeCAD
.. toctree::
:maxdepth: 4
.. automodule:: DocumentObject
.. autoclass:: ActiveDocument
:members:

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -1,5 +1,7 @@
/* FreeCAD sphinx CSS file */
@import url("/freecad.css");
body {
background: #191b26;
background-attachment: fixed;
@ -31,12 +33,8 @@ a.headerlink {
h1 {
font-size: 24px;
font-weight: bold;
margin: 0;
background: url("/images/freecad.png") top left no-repeat;
color: #000;
padding-left: 40px;
border-bottom: 1px solid #444;
letter-spacing: 1px;
border-bottom: 1px solid #888;
}
h2 {
@ -44,6 +42,10 @@ h2 {
margin: 30px 0 0 0;
}
ul {
margin: 0px 0px 0px;
}
.document {
background-color: #eee;
display: table;
@ -86,6 +88,11 @@ h2 {
padding: 10px;
}
.footer {
background: transparent;
color: #aaa;
}
@media print {
.document {

View File

@ -60,6 +60,7 @@ if commands.getstatusoutput("locate TemplatePyMod")[0] == 0:
import FreeCAD, FreeCADGui
FreeCADGui.showMainWindow() # this is needed for complete import of GUI modules
doc = FreeCAD.newDocument("doc")
# -- General configuration -----------------------------------------------------
@ -84,16 +85,16 @@ master_doc = 'index'
# General information about the project.
project = u'FreeCAD'
copyright = u'2011, Jürgen Riegel, Werner Mayer, Yorik van Havre'
copyright = u'2013, Jürgen Riegel, Werner Mayer, Yorik van Havre'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = '0.13'
version = '0.14'
# The full version, including alpha/beta/rc tags.
release = '0.13'
release = '0.14'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
@ -160,7 +161,7 @@ html_title = "FreeCAD API documentation"
# The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
html_favicon = None
html_favicon = "favicon.ico"
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,

View File

@ -277,7 +277,7 @@ StdCmdWhatsThis::StdCmdWhatsThis()
sToolTipText = QT_TR_NOOP("What's This");
sWhatsThis = "Std_WhatsThis";
sStatusTip = QT_TR_NOOP("What's This");
sAccel = keySequenceToAccel(QKeySequence::WhatsThis);
sAccel = keySequenceToAccel(QKeySequence::WhatsThis);
sPixmap = "WhatsThis";
eType = 0;
}
@ -421,7 +421,7 @@ StdCmdOnlineHelp::StdCmdOnlineHelp()
sWhatsThis = "Std_OnlineHelp";
sStatusTip = QT_TR_NOOP("Help");
sPixmap = "help-browser";
sAccel = keySequenceToAccel(QKeySequence::HelpContents);
sAccel = keySequenceToAccel(QKeySequence::HelpContents);
eType = 0;
}
@ -449,9 +449,9 @@ StdCmdOnlineHelpWebsite::StdCmdOnlineHelpWebsite()
void StdCmdOnlineHelpWebsite::activated(int iMsg)
{
ParameterGrp::handle hURLGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/OnlineHelp");
std::string url = hURLGrp->GetASCII("DownloadURL", "http://apps.sourceforge.net/mediawiki/free-cad/index.php?title=Online_Help_Toc");
OpenURLInBrowser(url.c_str());
ParameterGrp::handle hURLGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/OnlineHelp");
std::string url = hURLGrp->GetASCII("DownloadURL", "http://www.freecadweb.org/wiki/index.php?title=Online_Help_Toc");
OpenURLInBrowser(url.c_str());
}
//===========================================================================
@ -468,12 +468,105 @@ StdCmdFreeCADWebsite::StdCmdFreeCADWebsite()
sToolTipText = QT_TR_NOOP("The FreeCAD website");
sWhatsThis = "Std_FreeCADWebsite";
sStatusTip = QT_TR_NOOP("FreeCAD Website");
sPixmap = "internet-web-browser";
eType = 0;
}
void StdCmdFreeCADWebsite::activated(int iMsg)
{
OpenURLInBrowser("http://apps.sourceforge.net/mediawiki/free-cad/index.php?title=Main_Page");
OpenURLInBrowser("http://www.freecadweb.org");
}
//===========================================================================
// Std_FreeCADUserHub
//===========================================================================
DEF_STD_CMD(StdCmdFreeCADUserHub);
StdCmdFreeCADUserHub::StdCmdFreeCADUserHub()
:Command("Std_FreeCADUserHub")
{
sGroup = QT_TR_NOOP("Help");
sMenuText = QT_TR_NOOP("Users documentation");
sToolTipText = QT_TR_NOOP("Documentation for users on the FreeCAD website");
sWhatsThis = "Std_FreeCADUserHub";
sStatusTip = QT_TR_NOOP("Users documentation");
sPixmap = "internet-web-browser";
eType = 0;
}
void StdCmdFreeCADUserHub::activated(int iMsg)
{
OpenURLInBrowser("http://www.freecadweb.org/wiki/index.php?title=User_hub");
}
//===========================================================================
// Std_FreeCADPowerUserHub
//===========================================================================
DEF_STD_CMD(StdCmdFreeCADPowerUserHub);
StdCmdFreeCADPowerUserHub::StdCmdFreeCADPowerUserHub()
:Command("Std_FreeCADPowerUserHub")
{
sGroup = QT_TR_NOOP("Help");
sMenuText = QT_TR_NOOP("Python scripting documentation");
sToolTipText = QT_TR_NOOP("Python scripting documentation on the FreeCAD website");
sWhatsThis = "Std_FreeCADPowerUserHub";
sStatusTip = QT_TR_NOOP("PowerUsers documentation");
sPixmap = "internet-web-browser";
eType = 0;
}
void StdCmdFreeCADPowerUserHub::activated(int iMsg)
{
OpenURLInBrowser("http://www.freecadweb.org/wiki/index.php?title=Power_users_hub");
}
//===========================================================================
// Std_FreeCADForum
//===========================================================================
DEF_STD_CMD(StdCmdFreeCADForum);
StdCmdFreeCADForum::StdCmdFreeCADForum()
:Command("Std_FreeCADForum")
{
sGroup = QT_TR_NOOP("Help");
sMenuText = QT_TR_NOOP("FreeCAD Forum");
sToolTipText = QT_TR_NOOP("The FreeCAD forum, where you can find help from other users");
sWhatsThis = "Std_FreeCADForum";
sStatusTip = QT_TR_NOOP("The FreeCAD Forum");
sPixmap = "internet-web-browser";
eType = 0;
}
void StdCmdFreeCADForum::activated(int iMsg)
{
OpenURLInBrowser("http://sourceforge.net/apps/phpbb/free-cad");
}
//===========================================================================
// Std_FreeCADFAQ
//===========================================================================
DEF_STD_CMD(StdCmdFreeCADFAQ);
StdCmdFreeCADFAQ::StdCmdFreeCADFAQ()
:Command("Std_FreeCADFAQ")
{
sGroup = QT_TR_NOOP("Help");
sMenuText = QT_TR_NOOP("FreeCAD FAQ");
sToolTipText = QT_TR_NOOP("Frequently Asked Questions on the FreeCAD website");
sWhatsThis = "Std_FreeCADFAQ";
sStatusTip = QT_TR_NOOP("Frequently Asked Questions");
sPixmap = "internet-web-browser";
eType = 0;
}
void StdCmdFreeCADFAQ::activated(int iMsg)
{
OpenURLInBrowser("http://www.freecadweb.org/wiki/index.php?title=FAQ");
}
//===========================================================================
@ -490,13 +583,13 @@ StdCmdPythonWebsite::StdCmdPythonWebsite()
sToolTipText = QT_TR_NOOP("The official Python website");
sWhatsThis = "Std_PythonWebsite";
sStatusTip = QT_TR_NOOP("Python Website");
sPixmap = "python";
sPixmap = "applications-python";
eType = 0;
}
void StdCmdPythonWebsite::activated(int iMsg)
{
OpenURLInBrowser("http://python.org");
OpenURLInBrowser("http://python.org");
}
//===========================================================================
@ -575,6 +668,10 @@ void CreateStdCommands(void)
rcCmdMgr.addCommand(new StdCmdOnlineHelp());
rcCmdMgr.addCommand(new StdCmdOnlineHelpWebsite());
rcCmdMgr.addCommand(new StdCmdFreeCADWebsite());
rcCmdMgr.addCommand(new StdCmdFreeCADUserHub());
rcCmdMgr.addCommand(new StdCmdFreeCADPowerUserHub());
rcCmdMgr.addCommand(new StdCmdFreeCADForum());
rcCmdMgr.addCommand(new StdCmdFreeCADFAQ());
rcCmdMgr.addCommand(new StdCmdPythonWebsite());
//rcCmdMgr.addCommand(new StdCmdMeasurementSimple());
//rcCmdMgr.addCommand(new StdCmdDownloadOnlineHelp());

View File

@ -1,10 +1,8 @@
<ui version="4.0" >
<author></author>
<comment></comment>
<exportmacro></exportmacro>
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Gui::Dialog::DlgProjectInformation</class>
<widget class="QDialog" name="Gui::Dialog::DlgProjectInformation" >
<property name="geometry" >
<widget class="QDialog" name="Gui::Dialog::DlgProjectInformation">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
@ -12,220 +10,148 @@
<height>540</height>
</rect>
</property>
<property name="windowTitle" >
<property name="windowTitle">
<string>Project information</string>
</property>
<property name="sizeGripEnabled" >
<property name="sizeGripEnabled">
<bool>true</bool>
</property>
<property name="modal" >
<property name="modal">
<bool>true</bool>
</property>
<layout class="QGridLayout" >
<property name="margin" >
<layout class="QGridLayout">
<property name="margin">
<number>9</number>
</property>
<property name="spacing" >
<property name="spacing">
<number>6</number>
</property>
<item row="0" column="0" >
<widget class="QGroupBox" name="groupBoxInfo" >
<property name="title" >
<item row="0" column="0">
<widget class="QGroupBox" name="groupBoxInfo">
<property name="title">
<string>Information</string>
</property>
<layout class="QGridLayout" >
<property name="margin" >
<layout class="QGridLayout">
<property name="margin">
<number>9</number>
</property>
<property name="spacing" >
<property name="spacing">
<number>6</number>
</property>
<item row="0" column="0" >
<widget class="QLabel" name="textLabelName" >
<property name="text" >
<string>&amp;Name:</string>
</property>
<property name="alignment" >
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy" >
<cstring>lineEditName</cstring>
</property>
</widget>
</item>
<item row="0" column="1" >
<widget class="QLineEdit" name="lineEditName" >
<property name="minimumSize" >
<size>
<width>0</width>
<height>25</height>
</size>
</property>
<property name="readOnly" >
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0" >
<widget class="QLabel" name="textLabelPath" >
<property name="text" >
<string>Path:</string>
</property>
<property name="alignment" >
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="1" >
<widget class="QLineEdit" name="lineEditPath" >
<property name="minimumSize" >
<size>
<width>0</width>
<height>25</height>
</size>
</property>
<property name="readOnly" >
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="0" >
<widget class="QLabel" name="textLabelUuid" >
<property name="text" >
<string>UUID:</string>
</property>
<property name="alignment" >
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="2" column="1" >
<widget class="QLineEdit" name="lineEditUuid" >
<property name="minimumSize" >
<size>
<width>0</width>
<height>25</height>
</size>
</property>
<property name="readOnly" >
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="0" >
<widget class="QLabel" name="textLabelCreator" >
<property name="text" >
<string>Created &amp;by:</string>
</property>
<property name="alignment" >
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy" >
<cstring>lineEditCreator</cstring>
</property>
</widget>
</item>
<item row="3" column="1" >
<widget class="QLineEdit" name="lineEditCreator" >
<property name="minimumSize" >
<size>
<width>0</width>
<height>25</height>
</size>
</property>
</widget>
</item>
<item row="4" column="0" >
<widget class="QLabel" name="textLabelCreateDate" >
<property name="text" >
<string>Creation &amp;date:</string>
</property>
<property name="alignment" >
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy" >
<cstring>lineEditDate</cstring>
</property>
</widget>
</item>
<item row="4" column="1" >
<widget class="QLineEdit" name="lineEditDate" >
<property name="minimumSize" >
<size>
<width>0</width>
<height>25</height>
</size>
</property>
<property name="readOnly" >
<bool>true</bool>
</property>
</widget>
</item>
<item row="5" column="0" >
<widget class="QLabel" name="textLabelLastMod" >
<property name="text" >
<string>&amp;Last modified by:</string>
</property>
<property name="alignment" >
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy" >
<cstring>lineEditLastMod</cstring>
</property>
</widget>
</item>
<item row="5" column="1" >
<widget class="QLineEdit" name="lineEditLastMod" >
<property name="minimumSize" >
<size>
<width>0</width>
<height>25</height>
</size>
</property>
</widget>
</item>
<item row="6" column="0" >
<widget class="QLabel" name="textLabelLastModDate" >
<property name="text" >
<item row="6" column="0">
<widget class="QLabel" name="textLabelLastModDate">
<property name="text">
<string>Last &amp;modification date:</string>
</property>
<property name="alignment" >
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy" >
<property name="buddy">
<cstring>lineEditLastModDate</cstring>
</property>
</widget>
</item>
<item row="6" column="1" >
<widget class="QLineEdit" name="lineEditLastModDate" >
<property name="minimumSize" >
<item row="0" column="0">
<widget class="QLabel" name="textLabelName">
<property name="text">
<string>&amp;Name:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>lineEditName</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="lineEditName">
<property name="minimumSize">
<size>
<width>0</width>
<height>25</height>
</size>
</property>
<property name="readOnly" >
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="7" column="0" >
<widget class="QLabel" name="textLabelCompany" >
<property name="text" >
<string>Com&amp;pany:</string>
<item row="10" column="0">
<widget class="QLabel" name="textLabelComment">
<property name="text">
<string>Commen&amp;t:</string>
</property>
<property name="alignment" >
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy" >
<cstring>lineEditCompany</cstring>
<property name="buddy">
<cstring>textEditComment</cstring>
</property>
</widget>
</item>
<item row="7" column="1" >
<widget class="QLineEdit" name="lineEditCompany" >
<property name="minimumSize" >
<item row="1" column="0">
<widget class="QLabel" name="textLabelPath">
<property name="text">
<string>Path:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="lineEditPath">
<property name="minimumSize">
<size>
<width>0</width>
<height>25</height>
</size>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="textLabelUuid">
<property name="text">
<string>UUID:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="lineEditUuid">
<property name="minimumSize">
<size>
<width>0</width>
<height>25</height>
</size>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="textLabelCreator">
<property name="text">
<string>Created &amp;by:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>lineEditCreator</cstring>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="lineEditCreator">
<property name="minimumSize">
<size>
<width>0</width>
<height>25</height>
@ -233,31 +159,103 @@
</property>
</widget>
</item>
<item row="8" column="0" >
<widget class="QLabel" name="textLabelComment" >
<property name="text" >
<string>Commen&amp;t:</string>
<item row="4" column="0">
<widget class="QLabel" name="textLabelCreateDate">
<property name="text">
<string>Creation &amp;date:</string>
</property>
<property name="alignment" >
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy" >
<cstring>textEditComment</cstring>
<property name="buddy">
<cstring>lineEditDate</cstring>
</property>
</widget>
</item>
<item rowspan="2" row="8" column="1" >
<widget class="QTextEdit" name="textEditComment" />
<item row="4" column="1">
<widget class="QLineEdit" name="lineEditDate">
<property name="minimumSize">
<size>
<width>0</width>
<height>25</height>
</size>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="9" column="0" >
<item row="5" column="0">
<widget class="QLabel" name="textLabelLastMod">
<property name="text">
<string>&amp;Last modified by:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>lineEditLastMod</cstring>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QLineEdit" name="lineEditLastMod">
<property name="minimumSize">
<size>
<width>0</width>
<height>25</height>
</size>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QLineEdit" name="lineEditLastModDate">
<property name="minimumSize">
<size>
<width>0</width>
<height>25</height>
</size>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QLabel" name="textLabelCompany">
<property name="text">
<string>Com&amp;pany:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>lineEditCompany</cstring>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="QLineEdit" name="lineEditCompany">
<property name="minimumSize">
<size>
<width>0</width>
<height>25</height>
</size>
</property>
</widget>
</item>
<item row="10" column="1" rowspan="2">
<widget class="QTextEdit" name="textEditComment"/>
</item>
<item row="11" column="0">
<spacer>
<property name="orientation" >
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType" >
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" >
<property name="sizeHint" stdset="0">
<size>
<width>91</width>
<height>240</height>
@ -265,26 +263,63 @@
</property>
</spacer>
</item>
<item row="8" column="0">
<widget class="QLabel" name="textLabelLicense">
<property name="text">
<string>License information:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="9" column="0">
<widget class="QLabel" name="textLabelLicenseURL">
<property name="text">
<string>License URL</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="8" column="1">
<widget class="QLineEdit" name="lineEditLicense"/>
</item>
<item row="9" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLineEdit" name="lineEditLicenseURL"/>
</item>
<item>
<widget class="QPushButton" name="pushButtonOpenURL">
<property name="text">
<string>Open in browser</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item row="1" column="0" >
<layout class="QHBoxLayout" >
<property name="margin" >
<number>0</number>
</property>
<property name="spacing" >
<item row="1" column="0">
<layout class="QHBoxLayout">
<property name="spacing">
<number>6</number>
</property>
<property name="margin">
<number>0</number>
</property>
<item>
<spacer>
<property name="orientation" >
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType" >
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" >
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
@ -293,30 +328,30 @@
</spacer>
</item>
<item>
<widget class="QPushButton" name="buttonOk" >
<property name="text" >
<widget class="QPushButton" name="buttonOk">
<property name="text">
<string>&amp;OK</string>
</property>
<property name="shortcut" >
<property name="shortcut">
<string/>
</property>
<property name="autoDefault" >
<property name="autoDefault">
<bool>true</bool>
</property>
<property name="default" >
<property name="default">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="buttonCancel" >
<property name="text" >
<widget class="QPushButton" name="buttonCancel">
<property name="text">
<string>&amp;Cancel</string>
</property>
<property name="shortcut" >
<property name="shortcut">
<string/>
</property>
<property name="autoDefault" >
<property name="autoDefault">
<bool>true</bool>
</property>
</widget>
@ -325,9 +360,7 @@
</item>
</layout>
</widget>
<layoutdefault spacing="6" margin="11" />
<tabstops>
</tabstops>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections>
<connection>
@ -336,11 +369,11 @@
<receiver>Gui::Dialog::DlgProjectInformation</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel" >
<hint type="sourcelabel">
<x>20</x>
<y>20</y>
</hint>
<hint type="destinationlabel" >
<hint type="destinationlabel">
<x>20</x>
<y>20</y>
</hint>
@ -352,11 +385,11 @@
<receiver>Gui::Dialog::DlgProjectInformation</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel" >
<hint type="sourcelabel">
<x>20</x>
<y>20</y>
</hint>
<hint type="destinationlabel" >
<hint type="destinationlabel">
<x>20</x>
<y>20</y>
</hint>

View File

@ -28,6 +28,8 @@
#include "DlgProjectInformationImp.h"
#include "Document.h"
#include <QUrl>
#include <QDesktopServices>
using namespace Gui::Dialog;
@ -52,6 +54,8 @@ DlgProjectInformationImp::DlgProjectInformationImp( App::Document* doc, QWidget*
lineEditLastMod->setText(QString::fromUtf8(doc->LastModifiedBy.getValue()));
lineEditLastModDate->setText(QString::fromUtf8(doc->LastModifiedDate.getValue()));
lineEditCompany->setText(QString::fromUtf8(doc->Company.getValue()));
lineEditLicense->setText(QString::fromUtf8(doc->License.getValue()));
lineEditLicenseURL->setText(QString::fromUtf8(doc->LicenseURL.getValue()));
// When saving the text to XML the newlines get lost. So we store also the newlines as '\n'.
// See also accept().
@ -59,6 +63,7 @@ DlgProjectInformationImp::DlgProjectInformationImp( App::Document* doc, QWidget*
QStringList lines = comment.split(QLatin1String("\\n"), QString::KeepEmptyParts);
QString text = lines.join(QLatin1String("\n"));
textEditComment->setPlainText( text );
connect(pushButtonOpenURL, SIGNAL(clicked()),this, SLOT(open_url()));
}
/**
@ -77,6 +82,8 @@ void DlgProjectInformationImp::accept()
_doc->CreatedBy.setValue(lineEditCreator->text().toUtf8());
_doc->LastModifiedBy.setValue(lineEditCreator->text().toUtf8());
_doc->Company.setValue(lineEditCompany->text().toUtf8());
_doc->License.setValue(lineEditLicense->text().toUtf8());
_doc->LicenseURL.setValue(lineEditLicenseURL->text().toUtf8());
// Replace newline escape sequence trough '\\n' string
QStringList lines = textEditComment->toPlainText().split
@ -87,3 +94,11 @@ void DlgProjectInformationImp::accept()
QDialog::accept();
}
/**
* Opens the text in the LicenseURL property in external browser.
*/
void DlgProjectInformationImp::open_url()
{
QString url = QString::fromUtf8(_doc->LicenseURL.getValue());
QDesktopServices::openUrl(QUrl(url, QUrl::TolerantMode));
}

View File

@ -42,6 +42,7 @@ public:
protected:
void accept();
void open_url();
App::Document* _doc;
};

View File

@ -39,8 +39,8 @@ DlgSettingsMacroImp::DlgSettingsMacroImp( QWidget* parent )
{
this->setupUi(this);
if (MacroPath->fileName().isEmpty()) {
QDir d(QString::fromUtf8(App::GetApplication().GetHomePath()));
MacroPath->setFileName( d.path() );
QDir d(QString::fromUtf8(App::GetApplication().getUserAppDataDir().c_str()));
MacroPath->setFileName(d.path());
}
}

View File

@ -66,15 +66,6 @@ void DlgSettingsViewColor::saveSettings()
checkBoxSelection->onSave();
HighlightColor->onSave();
SelectionColor->onSave();
CursorTextColor->onSave();
EditedEdgeColor->onSave();
EditedVertexColor->onSave();
ConstructionColor->onSave();
FullyConstrainedColor->onSave();
BoundingBoxColor->onSave();
DefaultShapeColor->onSave();
DefaultShapeLineColor->onSave();
DefaultShapeLineWidth->onSave();
}
void DlgSettingsViewColor::loadSettings()
@ -90,15 +81,6 @@ void DlgSettingsViewColor::loadSettings()
checkBoxSelection->onRestore();
HighlightColor->onRestore();
SelectionColor->onRestore();
CursorTextColor->onRestore();
EditedEdgeColor->onRestore();
EditedVertexColor->onRestore();
ConstructionColor->onRestore();
FullyConstrainedColor->onRestore();
BoundingBoxColor->onRestore();
DefaultShapeColor->onRestore();
DefaultShapeLineColor->onRestore();
DefaultShapeLineWidth->onRestore();
}
/**

View File

@ -148,7 +148,7 @@
</layout>
</widget>
</item>
<item row="2" column="0">
<item row="1" column="0">
<widget class="QGroupBox" name="groupBoxColor">
<property name="title">
<string>Background color</string>
@ -342,7 +342,7 @@
</layout>
</widget>
</item>
<item row="3" column="0">
<item row="2" column="0">
<spacer name="spacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
@ -355,296 +355,6 @@
</property>
</spacer>
</item>
<item row="1" column="0">
<widget class="QGroupBox" name="groupBoxDefaultColors">
<property name="title">
<string>Default colors</string>
</property>
<layout class="QGridLayout" name="colgridLayout">
<item row="2" column="1">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="0">
<layout class="QGridLayout" name="_2">
<property name="margin">
<number>0</number>
</property>
<property name="spacing">
<number>6</number>
</property>
<item row="1" column="0">
<widget class="QLabel" name="label">
<property name="minimumSize">
<size>
<width>240</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Edited edge color</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Edited vertex color</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Construction geometry</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Fully constrained geometry</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="Gui::PrefColorButton" name="ConstructionColor">
<property name="toolTip">
<string>The color of construction geometry in edit mode</string>
</property>
<property name="color">
<color>
<red>0</red>
<green>0</green>
<blue>220</blue>
</color>
</property>
<property name="prefEntry" stdset="0">
<cstring>ConstructionColor</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>View</cstring>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="Gui::PrefColorButton" name="FullyConstrainedColor">
<property name="toolTip">
<string>The color of fully constrained geometry in edit mode</string>
</property>
<property name="color">
<color>
<red>0</red>
<green>255</green>
<blue>0</blue>
</color>
</property>
<property name="prefEntry" stdset="0">
<cstring>FullyConstrainedColor</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>View</cstring>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="Gui::PrefColorButton" name="EditedVertexColor">
<property name="toolTip">
<string>The color of vertices being edited</string>
</property>
<property name="color">
<color>
<red>255</red>
<green>38</green>
<blue>0</blue>
</color>
</property>
<property name="prefEntry" stdset="0">
<cstring>EditedVertexColor</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>View</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="Gui::PrefColorButton" name="EditedEdgeColor">
<property name="toolTip">
<string>The color of edges being edited</string>
</property>
<property name="color">
<color>
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</property>
<property name="prefEntry" stdset="0">
<cstring>EditedEdgeColor</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>View</cstring>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Cursor text color</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="Gui::PrefColorButton" name="CursorTextColor">
<property name="color">
<color>
<red>0</red>
<green>0</green>
<blue>255</blue>
</color>
</property>
<property name="prefEntry" stdset="0">
<cstring>CursorTextColor</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>View</cstring>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Bounding box color</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="Gui::PrefColorButton" name="BoundingBoxColor">
<property name="toolTip">
<string>The color of bounding boxes in the 3D view</string>
</property>
<property name="color">
<color>
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</property>
<property name="prefEntry" stdset="0">
<cstring>BoundingBoxColor</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>View</cstring>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="0">
<layout class="QGridLayout" name="_1">
<item row="0" column="0">
<widget class="QLabel" name="label_6">
<property name="minimumSize">
<size>
<width>240</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Default shape color</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="Gui::PrefColorButton" name="DefaultShapeColor">
<property name="toolTip">
<string>The default color for new shapes</string>
</property>
<property name="color">
<color>
<red>204</red>
<green>204</green>
<blue>204</blue>
</color>
</property>
<property name="prefEntry" stdset="0">
<cstring>DefaultShapeColor</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>View</cstring>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<layout class="QGridLayout" name="_5">
<item row="0" column="0">
<widget class="QLabel" name="label_7">
<property name="minimumSize">
<size>
<width>182</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Default line width and color</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="Gui::PrefColorButton" name="DefaultShapeLineColor">
<property name="toolTip">
<string>The default line color for new shapes</string>
</property>
<property name="color">
<color>
<red>25</red>
<green>25</green>
<blue>25</blue>
</color>
</property>
<property name="prefEntry" stdset="0">
<cstring>DefaultShapeLineColor</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>View</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="Gui::PrefSpinBox" name="DefaultShapeLineWidth">
<property name="toolTip">
<string>The default line thickness for new shapes</string>
</property>
<property name="suffix">
<string>px</string>
</property>
<property name="value">
<number>2</number>
</property>
<property name="prefEntry" stdset="0">
<cstring>DefaultShapeLineWidth</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>View</cstring>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<customwidgets>
@ -653,11 +363,6 @@
<extends>QPushButton</extends>
<header>Gui/Widgets.h</header>
</customwidget>
<customwidget>
<class>Gui::PrefSpinBox</class>
<extends>QSpinBox</extends>
<header>Gui/PrefWidgets.h</header>
</customwidget>
<customwidget>
<class>Gui::PrefColorButton</class>
<extends>Gui::ColorButton</extends>
@ -679,15 +384,6 @@
<tabstop>checkBoxSelection</tabstop>
<tabstop>HighlightColor</tabstop>
<tabstop>SelectionColor</tabstop>
<tabstop>DefaultShapeColor</tabstop>
<tabstop>DefaultShapeLineWidth</tabstop>
<tabstop>DefaultShapeLineColor</tabstop>
<tabstop>CursorTextColor</tabstop>
<tabstop>EditedEdgeColor</tabstop>
<tabstop>EditedVertexColor</tabstop>
<tabstop>ConstructionColor</tabstop>
<tabstop>FullyConstrainedColor</tabstop>
<tabstop>BoundingBoxColor</tabstop>
<tabstop>radioButtonSimple</tabstop>
<tabstop>SelectionColor_Background</tabstop>
<tabstop>radioButtonGradient</tabstop>

View File

@ -0,0 +1,142 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="64px"
height="64px"
id="svg3065"
version="1.1"
inkscape:version="0.48.4 r9939"
sodipodi:docname="New document 2">
<defs
id="defs3067">
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient2795"
id="radialGradient3023"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0,-0.1143588,0.5026551,1.8070519e-7,-11.472507,114.13954)"
cx="61.518883"
cy="132.28575"
fx="61.518883"
fy="132.28575"
r="29.036913" />
<linearGradient
id="linearGradient2795">
<stop
style="stop-color:#b8b8b8;stop-opacity:0.49803922"
offset="0"
id="stop2797" />
<stop
style="stop-color:#7f7f7f;stop-opacity:0"
offset="1"
id="stop2799" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4671"
id="linearGradient3027"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.30307123,0,0,0.3059972,-6.2026572,-4.4262311)"
x1="150.96111"
y1="192.35176"
x2="112.03144"
y2="137.27299" />
<linearGradient
id="linearGradient4671">
<stop
style="stop-color:#ffd43b;stop-opacity:1"
offset="0"
id="stop4673" />
<stop
style="stop-color:#ffe873;stop-opacity:1"
offset="1"
id="stop4675" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4689"
id="linearGradient3030"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.562541,0,0,0.567972,-9.399749,-5.305317)"
x1="26.648937"
y1="20.603781"
x2="135.66525"
y2="114.39767" />
<linearGradient
id="linearGradient4689">
<stop
style="stop-color:#5a9fd4;stop-opacity:1"
offset="0"
id="stop4691" />
<stop
style="stop-color:#306998;stop-opacity:1"
offset="1"
id="stop4693" />
</linearGradient>
<linearGradient
y2="114.39767"
x2="135.66525"
y1="20.603781"
x1="26.648937"
gradientTransform="matrix(0.30307123,0,0,0.3059972,-6.2026572,-4.4262311)"
gradientUnits="userSpaceOnUse"
id="linearGradient3063"
xlink:href="#linearGradient4689"
inkscape:collect="always" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="2.75"
inkscape:cx="17.977135"
inkscape:cy="29.602256"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:document-units="px"
inkscape:grid-bbox="true"
inkscape:window-width="688"
inkscape:window-height="518"
inkscape:window-x="0"
inkscape:window-y="22"
inkscape:window-maximized="0" />
<metadata
id="metadata3070">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer">
<path
inkscape:connector-curvature="0"
d="m 31.461584,1.8789638 c -2.469461,0.011474 -4.827741,0.2220839 -6.902785,0.5892627 -6.112821,1.0799344 -7.222671,3.3403304 -7.222671,7.5088844 l 0,5.5053921 14.445341,0 0,1.835132 -14.445341,0 -5.421213,0 c -4.1982177,0 -7.8742982,2.523371 -9.0241292,7.323687 -1.3263152,5.502276 -1.3851452,8.935787 0,14.681047 1.0268266,4.276549 3.4790273,7.323686 7.6772442,7.323687 l 4.966638,0 0,-6.599737 c 0,-4.76792 4.125318,-8.97362 9.024131,-8.973622 l 14.428506,0 c 4.016385,0 7.222672,-3.306959 7.222671,-7.340523 l 0,-13.7550631 c 0,-3.9147689 -3.302552,-6.8555252 -7.222671,-7.5088844 C 36.505811,2.0551496 33.931046,1.867489 31.461584,1.8789638 z m -7.811932,4.4278849 c 1.492104,0 2.710605,1.2384043 2.710605,2.7611137 -1e-6,1.5173126 -1.218501,2.7442786 -2.710605,2.7442786 -1.497455,0 -2.710607,-1.226966 -2.710607,-2.7442786 0,-1.5227082 1.213152,-2.7611137 2.710607,-2.7611137 z"
style="fill:url(#linearGradient3063);fill-opacity:1"
id="path1948" />
<path
inkscape:connector-curvature="0"
d="m 48.011435,17.317635 0,6.414539 c 0,4.973107 -4.216233,9.158818 -9.02413,9.158819 l -14.428506,0 c -3.95221,0 -7.222671,3.382557 -7.222671,7.340524 l 0,13.755061 c 0,3.914773 3.404164,6.217396 7.222671,7.340526 4.572583,1.344523 8.957451,1.587505 14.428506,0 3.636673,-1.052936 7.222672,-3.171974 7.222671,-7.340526 l 0,-5.505391 -14.428507,0 0,-1.835131 14.428507,0 7.222673,0 c 4.19822,0 5.762648,-2.928347 7.222666,-7.323687 1.508151,-4.524934 1.44398,-8.87639 0,-14.681047 -1.037521,-4.179353 -3.019107,-7.323687 -7.222666,-7.323687 l -5.421214,0 z M 39.896452,52.15145 c 1.497455,1e-6 2.710606,1.226966 2.710606,2.744276 -1e-6,1.522709 -1.213153,2.761117 -2.710606,2.761117 -1.492106,0 -2.710606,-1.238408 -2.710606,-2.761117 1e-6,-1.51731 1.218498,-2.744276 2.710606,-2.744276 z"
style="fill:url(#linearGradient3027);fill-opacity:1"
id="path1950" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.7 KiB

View File

@ -0,0 +1,982 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="48px"
height="48px"
id="svg3440"
sodipodi:version="0.32"
inkscape:version="0.46"
sodipodi:docbase="/home/jimmac/src/cvs/tango-icon-theme/scalable/apps"
sodipodi:docname="internet-web-browser.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape">
<defs
id="defs3">
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 24 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="48 : 24 : 1"
inkscape:persp3d-origin="24 : 16 : 1"
id="perspective156" />
<linearGradient
id="linearGradient4750">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop4752" />
<stop
style="stop-color:#fefefe;stop-opacity:1.0000000;"
offset="0.37931034"
id="stop4758" />
<stop
style="stop-color:#1d1d1d;stop-opacity:1.0000000;"
offset="1.0000000"
id="stop4754" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient4350">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop4352" />
<stop
style="stop-color:#ffffff;stop-opacity:0;"
offset="1"
id="stop4354" />
</linearGradient>
<linearGradient
id="linearGradient4126">
<stop
style="stop-color:#ffffff;stop-opacity:1.0000000;"
offset="0.0000000"
id="stop4128" />
<stop
style="stop-color:#ffffff;stop-opacity:0.16494845;"
offset="1.0000000"
id="stop4130" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient4114">
<stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop4116" />
<stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop4118" />
</linearGradient>
<linearGradient
id="linearGradient3962">
<stop
style="stop-color:#d3e9ff;stop-opacity:1.0000000;"
offset="0.0000000"
id="stop3964" />
<stop
style="stop-color:#d3e9ff;stop-opacity:1.0000000;"
offset="0.15517241"
id="stop4134" />
<stop
style="stop-color:#4074ae;stop-opacity:1.0000000;"
offset="0.75000000"
id="stop4346" />
<stop
style="stop-color:#36486c;stop-opacity:1.0000000;"
offset="1.0000000"
id="stop3966" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3962"
id="radialGradient3968"
gradientTransform="scale(0.999989,1.000011)"
cx="18.247644"
cy="15.716079"
fx="18.247644"
fy="15.716079"
r="29.993349"
gradientUnits="userSpaceOnUse" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient4114"
id="radialGradient4120"
gradientTransform="scale(1.643990,0.608276)"
cx="15.115514"
cy="63.965388"
fx="15.115514"
fy="63.965388"
r="12.289036"
gradientUnits="userSpaceOnUse" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient4126"
id="radialGradient4132"
gradientTransform="scale(0.999989,1.000011)"
cx="15.601279"
cy="12.142302"
fx="15.601279"
fy="12.142302"
r="43.526714"
gradientUnits="userSpaceOnUse" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient4350"
id="radialGradient4356"
gradientTransform="scale(1.179536,0.847791)"
cx="11.826907"
cy="10.476453"
fx="11.826907"
fy="10.476453"
r="32.664848"
gradientUnits="userSpaceOnUse" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient4750"
id="radialGradient4756"
gradientTransform="scale(1.036822,0.964486)"
cx="18.633780"
cy="17.486208"
fx="18.934305"
fy="17.810213"
r="40.692665"
gradientUnits="userSpaceOnUse" />
<radialGradient
r="40.692665"
fy="17.810213"
fx="18.934305"
cy="17.486208"
cx="18.633780"
gradientTransform="scale(1.036822,0.964486)"
gradientUnits="userSpaceOnUse"
id="radialGradient1460"
xlink:href="#linearGradient4750"
inkscape:collect="always" />
<radialGradient
r="40.692665"
fy="17.810213"
fx="18.934305"
cy="17.486208"
cx="18.633780"
gradientTransform="scale(1.036822,0.964486)"
gradientUnits="userSpaceOnUse"
id="radialGradient1462"
xlink:href="#linearGradient4750"
inkscape:collect="always" />
<radialGradient
r="40.692665"
fy="17.810213"
fx="18.934305"
cy="17.486208"
cx="18.633780"
gradientTransform="scale(1.036822,0.964486)"
gradientUnits="userSpaceOnUse"
id="radialGradient1466"
xlink:href="#linearGradient4750"
inkscape:collect="always" />
<radialGradient
r="40.692665"
fy="17.810213"
fx="18.934305"
cy="17.486208"
cx="18.633780"
gradientTransform="scale(1.036822,0.964486)"
gradientUnits="userSpaceOnUse"
id="radialGradient1468"
xlink:href="#linearGradient4750"
inkscape:collect="always" />
<radialGradient
r="40.692665"
fy="17.810213"
fx="18.934305"
cy="17.486208"
cx="18.633780"
gradientTransform="scale(1.036822,0.964486)"
gradientUnits="userSpaceOnUse"
id="radialGradient1470"
xlink:href="#linearGradient4750"
inkscape:collect="always" />
<radialGradient
r="40.692665"
fy="17.810213"
fx="18.934305"
cy="17.486208"
cx="18.633780"
gradientTransform="scale(1.036822,0.964486)"
gradientUnits="userSpaceOnUse"
id="radialGradient1474"
xlink:href="#linearGradient4750"
inkscape:collect="always" />
<radialGradient
r="40.692665"
fy="17.810213"
fx="18.934305"
cy="17.486208"
cx="18.633780"
gradientTransform="scale(1.036822,0.964486)"
gradientUnits="userSpaceOnUse"
id="radialGradient1476"
xlink:href="#linearGradient4750"
inkscape:collect="always" />
<radialGradient
r="40.692665"
fy="17.810213"
fx="18.934305"
cy="17.486208"
cx="18.633780"
gradientTransform="scale(1.036822,0.964486)"
gradientUnits="userSpaceOnUse"
id="radialGradient1478"
xlink:href="#linearGradient4750"
inkscape:collect="always" />
<radialGradient
r="40.692665"
fy="17.810213"
fx="18.934305"
cy="17.486208"
cx="18.633780"
gradientTransform="scale(1.036822,0.964486)"
gradientUnits="userSpaceOnUse"
id="radialGradient1482"
xlink:href="#linearGradient4750"
inkscape:collect="always" />
<radialGradient
r="40.692665"
fy="17.810213"
fx="18.934305"
cy="17.486208"
cx="18.633780"
gradientTransform="scale(1.036822,0.964486)"
gradientUnits="userSpaceOnUse"
id="radialGradient1484"
xlink:href="#linearGradient4750"
inkscape:collect="always" />
<radialGradient
r="40.692665"
fy="17.810213"
fx="18.934305"
cy="17.486208"
cx="18.633780"
gradientTransform="scale(1.036822,0.964486)"
gradientUnits="userSpaceOnUse"
id="radialGradient1486"
xlink:href="#linearGradient4750"
inkscape:collect="always" />
<radialGradient
r="40.692665"
fy="17.810213"
fx="18.934305"
cy="17.486208"
cx="18.633780"
gradientTransform="scale(1.036822,0.964486)"
gradientUnits="userSpaceOnUse"
id="radialGradient1490"
xlink:href="#linearGradient4750"
inkscape:collect="always" />
<radialGradient
r="40.692665"
fy="17.810213"
fx="18.934305"
cy="17.486208"
cx="18.633780"
gradientTransform="scale(1.036822,0.964486)"
gradientUnits="userSpaceOnUse"
id="radialGradient1492"
xlink:href="#linearGradient4750"
inkscape:collect="always" />
<radialGradient
r="40.692665"
fy="17.810213"
fx="18.934305"
cy="17.486208"
cx="18.633780"
gradientTransform="scale(1.036822,0.964486)"
gradientUnits="userSpaceOnUse"
id="radialGradient1494"
xlink:href="#linearGradient4750"
inkscape:collect="always" />
<radialGradient
r="40.692665"
fy="17.810213"
fx="18.934305"
cy="17.486208"
cx="18.633780"
gradientTransform="scale(1.036822,0.964486)"
gradientUnits="userSpaceOnUse"
id="radialGradient1498"
xlink:href="#linearGradient4750"
inkscape:collect="always" />
<radialGradient
r="40.692665"
fy="17.810213"
fx="18.934305"
cy="17.486208"
cx="18.633780"
gradientTransform="scale(1.036822,0.964486)"
gradientUnits="userSpaceOnUse"
id="radialGradient1500"
xlink:href="#linearGradient4750"
inkscape:collect="always" />
<radialGradient
r="40.692665"
fy="17.810213"
fx="18.934305"
cy="17.486208"
cx="18.633780"
gradientTransform="scale(1.036822,0.964486)"
gradientUnits="userSpaceOnUse"
id="radialGradient1502"
xlink:href="#linearGradient4750"
inkscape:collect="always" />
<radialGradient
r="40.692665"
fy="17.810213"
fx="18.934305"
cy="17.486208"
cx="18.633780"
gradientTransform="scale(1.036822,0.964486)"
gradientUnits="userSpaceOnUse"
id="radialGradient1506"
xlink:href="#linearGradient4750"
inkscape:collect="always" />
<radialGradient
r="40.692665"
fy="17.810213"
fx="18.934305"
cy="17.486208"
cx="18.633780"
gradientTransform="scale(1.036822,0.964486)"
gradientUnits="userSpaceOnUse"
id="radialGradient1508"
xlink:href="#linearGradient4750"
inkscape:collect="always" />
<radialGradient
r="40.692665"
fy="17.810213"
fx="18.934305"
cy="17.486208"
cx="18.633780"
gradientTransform="scale(1.036822,0.964486)"
gradientUnits="userSpaceOnUse"
id="radialGradient1510"
xlink:href="#linearGradient4750"
inkscape:collect="always" />
<radialGradient
r="40.692665"
fy="17.810213"
fx="18.934305"
cy="17.486208"
cx="18.633780"
gradientTransform="scale(1.036822,0.964486)"
gradientUnits="userSpaceOnUse"
id="radialGradient1514"
xlink:href="#linearGradient4750"
inkscape:collect="always" />
<radialGradient
r="40.692665"
fy="17.810213"
fx="18.934305"
cy="17.486208"
cx="18.633780"
gradientTransform="scale(1.036822,0.964486)"
gradientUnits="userSpaceOnUse"
id="radialGradient1516"
xlink:href="#linearGradient4750"
inkscape:collect="always" />
<radialGradient
r="40.692665"
fy="17.810213"
fx="18.934305"
cy="17.486208"
cx="18.633780"
gradientTransform="scale(1.036822,0.964486)"
gradientUnits="userSpaceOnUse"
id="radialGradient1518"
xlink:href="#linearGradient4750"
inkscape:collect="always" />
<radialGradient
r="40.692665"
fy="17.810213"
fx="18.934305"
cy="17.486208"
cx="18.633780"
gradientTransform="scale(1.036822,0.964486)"
gradientUnits="userSpaceOnUse"
id="radialGradient1522"
xlink:href="#linearGradient4750"
inkscape:collect="always" />
<radialGradient
r="40.692665"
fy="17.810213"
fx="18.934305"
cy="17.486208"
cx="18.633780"
gradientTransform="scale(1.036822,0.964486)"
gradientUnits="userSpaceOnUse"
id="radialGradient1524"
xlink:href="#linearGradient4750"
inkscape:collect="always" />
<radialGradient
r="40.692665"
fy="17.810213"
fx="18.934305"
cy="17.486208"
cx="18.633780"
gradientTransform="scale(1.036822,0.964486)"
gradientUnits="userSpaceOnUse"
id="radialGradient1526"
xlink:href="#linearGradient4750"
inkscape:collect="always" />
<radialGradient
r="40.692665"
fy="17.810213"
fx="18.934305"
cy="17.486208"
cx="18.633780"
gradientTransform="scale(1.036822,0.964486)"
gradientUnits="userSpaceOnUse"
id="radialGradient1528"
xlink:href="#linearGradient4750"
inkscape:collect="always" />
<radialGradient
r="40.692665"
fy="17.810213"
fx="18.934305"
cy="17.486208"
cx="18.633780"
gradientTransform="scale(1.036822,0.964486)"
gradientUnits="userSpaceOnUse"
id="radialGradient1530"
xlink:href="#linearGradient4750"
inkscape:collect="always" />
<radialGradient
r="40.692665"
fy="17.810213"
fx="18.934305"
cy="17.486208"
cx="18.633780"
gradientTransform="scale(1.036822,0.964486)"
gradientUnits="userSpaceOnUse"
id="radialGradient1532"
xlink:href="#linearGradient4750"
inkscape:collect="always" />
<radialGradient
r="40.692665"
fy="17.810213"
fx="18.934305"
cy="17.486208"
cx="18.633780"
gradientTransform="scale(1.036822,0.964486)"
gradientUnits="userSpaceOnUse"
id="radialGradient1534"
xlink:href="#linearGradient4750"
inkscape:collect="always" />
<radialGradient
r="40.692665"
fy="17.810213"
fx="18.934305"
cy="17.486208"
cx="18.633780"
gradientTransform="scale(1.036822,0.964486)"
gradientUnits="userSpaceOnUse"
id="radialGradient1536"
xlink:href="#linearGradient4750"
inkscape:collect="always" />
<radialGradient
r="40.692665"
fy="17.810213"
fx="18.934305"
cy="17.486208"
cx="18.633780"
gradientTransform="scale(1.036822,0.964486)"
gradientUnits="userSpaceOnUse"
id="radialGradient1538"
xlink:href="#linearGradient4750"
inkscape:collect="always" />
<radialGradient
r="40.692665"
fy="17.810213"
fx="18.934305"
cy="17.486208"
cx="18.633780"
gradientTransform="scale(1.036822,0.964486)"
gradientUnits="userSpaceOnUse"
id="radialGradient1540"
xlink:href="#linearGradient4750"
inkscape:collect="always" />
<radialGradient
r="40.692665"
fy="17.810213"
fx="18.934305"
cy="17.486208"
cx="18.633780"
gradientTransform="scale(1.036822,0.964486)"
gradientUnits="userSpaceOnUse"
id="radialGradient1542"
xlink:href="#linearGradient4750"
inkscape:collect="always" />
<radialGradient
r="40.692665"
fy="17.810213"
fx="18.934305"
cy="17.486208"
cx="18.633780"
gradientTransform="scale(1.036822,0.964486)"
gradientUnits="userSpaceOnUse"
id="radialGradient1544"
xlink:href="#linearGradient4750"
inkscape:collect="always" />
<radialGradient
r="40.692665"
fy="17.810213"
fx="18.934305"
cy="17.486208"
cx="18.633780"
gradientTransform="scale(1.036822,0.964486)"
gradientUnits="userSpaceOnUse"
id="radialGradient1546"
xlink:href="#linearGradient4750"
inkscape:collect="always" />
<radialGradient
r="40.692665"
fy="17.810213"
fx="18.934305"
cy="17.486208"
cx="18.633780"
gradientTransform="scale(1.036822,0.964486)"
gradientUnits="userSpaceOnUse"
id="radialGradient1550"
xlink:href="#linearGradient4750"
inkscape:collect="always" />
<radialGradient
r="40.692665"
fy="17.810213"
fx="18.934305"
cy="17.486208"
cx="18.633780"
gradientTransform="scale(1.036822,0.964486)"
gradientUnits="userSpaceOnUse"
id="radialGradient1552"
xlink:href="#linearGradient4750"
inkscape:collect="always" />
<radialGradient
r="40.692665"
fy="17.810213"
fx="18.934305"
cy="17.486208"
cx="18.633780"
gradientTransform="scale(1.036822,0.964486)"
gradientUnits="userSpaceOnUse"
id="radialGradient1554"
xlink:href="#linearGradient4750"
inkscape:collect="always" />
<radialGradient
r="40.692665"
fy="17.810213"
fx="18.934305"
cy="17.486208"
cx="18.633780"
gradientTransform="scale(1.036822,0.964486)"
gradientUnits="userSpaceOnUse"
id="radialGradient1558"
xlink:href="#linearGradient4750"
inkscape:collect="always" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="0.17254902"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="9.8994949"
inkscape:cx="25.799661"
inkscape:cy="24.622653"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:grid-bbox="true"
inkscape:document-units="px"
inkscape:window-width="1440"
inkscape:window-height="823"
inkscape:window-x="0"
inkscape:window-y="30"
inkscape:showpageshadow="false" />
<metadata
id="metadata4">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title>Globe</dc:title>
<dc:creator>
<cc:Agent>
<dc:title>Jakub Steiner</dc:title>
</cc:Agent>
</dc:creator>
<dc:contributor>
<cc:Agent>
<dc:title>Tuomas Kuosmanen</dc:title>
</cc:Agent>
</dc:contributor>
<cc:license
rdf:resource="http://creativecommons.org/licenses/publicdomain/" />
<dc:source>http://jimmac.musichall.cz</dc:source>
<dc:subject>
<rdf:Bag>
<rdf:li>globe</rdf:li>
<rdf:li>international</rdf:li>
<rdf:li>web</rdf:li>
<rdf:li>www</rdf:li>
<rdf:li>internet</rdf:li>
<rdf:li>network</rdf:li>
</rdf:Bag>
</dc:subject>
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/licenses/publicdomain/">
<cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
</cc:License>
</rdf:RDF>
</metadata>
<g
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer">
<path
sodipodi:type="arc"
style="fill:url(#radialGradient4120);fill-opacity:1.0000000;stroke:none;stroke-opacity:1.0000000"
id="path4112"
sodipodi:cx="24.849752"
sodipodi:cy="38.908627"
sodipodi:rx="20.203051"
sodipodi:ry="7.4751287"
d="M 45.052803 38.908627 A 20.203051 7.4751287 0 1 1 4.6467018,38.908627 A 20.203051 7.4751287 0 1 1 45.052803 38.908627 z"
transform="matrix(1.000000,0.000000,0.000000,1.243244,0.000000,-10.27241)" />
<path
style="fill:url(#radialGradient3968);fill-opacity:1.0000000;fill-rule:nonzero;stroke:#39396c;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000"
d="M 43.959853,23.485499 C 43.959853,34.195217 35.277750,42.877222 24.569505,42.877222 C 13.860279,42.877222 5.1786663,34.195119 5.1786663,23.485499 C 5.1786663,12.776272 13.860279,4.0951517 24.569505,4.0951517 C 35.277750,4.0951517 43.959853,12.776272 43.959853,23.485499 L 43.959853,23.485499 z "
id="path3214" />
<path
sodipodi:type="arc"
style="opacity:0.42159382;fill:url(#radialGradient4356);fill-opacity:1.0000000;stroke:none;stroke-opacity:1.0000000"
id="path4348"
sodipodi:cx="17.778685"
sodipodi:cy="15.271057"
sodipodi:rx="12.929953"
sodipodi:ry="9.2934036"
d="M 30.708637 15.271057 A 12.929953 9.2934036 0 1 1 4.8487320,15.271057 A 12.929953 9.2934036 0 1 1 30.708637 15.271057 z"
transform="matrix(0.835938,0.000000,0.000000,1.000000,9.886868,0.000000)" />
<g
id="g4136"
style="fill:#000000;fill-opacity:0.71345031;fill-rule:nonzero;stroke:none;stroke-miterlimit:4.0000000"
transform="matrix(0.982371,0.000000,0.000000,0.982371,0.121079,0.232914)">
<g
id="g4138">
<g
id="g4142">
<path
d="M 44.071300,20.714400 C 44.071300,20.977100 44.071300,20.714400 44.071300,20.714400 L 43.526400,21.331600 C 43.192400,20.938000 42.817400,20.607000 42.436600,20.261300 L 41.600700,20.384300 L 40.837000,19.521000 L 40.837000,20.589400 L 41.491300,21.084500 L 41.926800,21.577700 L 42.508800,20.919500 C 42.655300,21.193900 42.799800,21.468300 42.945300,21.742700 L 42.945300,22.565000 L 42.290000,23.305200 L 41.090800,24.128400 L 40.182600,25.034700 L 39.600600,24.374500 L 39.891600,23.634300 L 39.310500,22.976100 L 38.329100,20.878400 L 37.493200,19.933100 L 37.274400,20.179200 L 37.602500,21.372600 L 38.219700,22.071800 C 38.572200,23.089400 38.920900,24.062000 39.383800,25.034700 C 40.101600,25.034700 40.778300,24.958500 41.491200,24.868700 L 41.491200,25.444900 L 40.619100,27.584100 L 39.819300,28.488400 L 39.165000,29.888800 C 39.165000,30.656400 39.165000,31.424000 39.165000,32.191500 L 39.383800,33.097800 L 39.020500,33.508000 L 38.219700,34.002100 L 37.383800,34.701300 L 38.075200,35.482600 L 37.129900,36.306800 L 37.311500,36.840000 L 35.893500,38.445500 L 34.949200,38.445500 L 34.149400,38.939600 L 33.639600,38.939600 L 33.639600,38.281400 L 33.422800,36.963000 C 33.141500,36.136800 32.848600,35.316500 32.550700,34.496200 C 32.550700,33.890700 32.586800,33.291100 32.623000,32.685700 L 32.987300,31.863400 L 32.477500,30.875100 L 32.514600,29.517700 L 31.823200,28.736400 L 32.168900,27.605500 L 31.606400,26.967300 L 30.624000,26.967300 L 30.296900,26.597200 L 29.315500,27.214900 L 28.916100,26.761300 L 28.006900,27.543000 C 27.389700,26.843300 26.771500,26.144100 26.153400,25.444900 L 25.426800,23.716400 L 26.081100,22.730100 L 25.717800,22.319000 L 26.516600,20.425400 C 27.172900,19.609000 27.858400,18.825800 28.551800,18.039700 L 29.788100,17.710600 L 31.169000,17.546500 L 32.114300,17.793600 L 33.459000,19.150000 L 33.931700,18.615800 L 34.585000,18.533800 L 35.821300,18.944900 L 36.766600,18.944900 L 37.420900,18.368700 L 37.711900,17.957600 L 37.056600,17.546500 L 35.965800,17.464500 C 35.663100,17.044600 35.381800,16.603200 35.022400,16.230100 L 34.658100,16.394200 L 34.512600,17.464500 L 33.858300,16.724300 L 33.713800,15.900100 L 32.987200,15.325900 L 32.695200,15.325900 L 33.422700,16.148200 L 33.131700,16.888400 L 32.550600,17.052500 L 32.913900,16.312300 L 32.258600,15.984200 L 31.678500,15.326000 L 30.586700,15.572100 L 30.442200,15.900200 L 29.787900,16.312300 L 29.424600,17.217600 L 28.516400,17.669700 L 28.116000,17.217600 L 27.680500,17.217600 L 27.680500,15.736200 L 28.625800,15.242100 L 29.352400,15.242100 L 29.205900,14.666900 L 28.625800,14.090700 L 29.606300,13.884600 L 30.151200,13.268400 L 30.586700,12.527200 L 31.387500,12.527200 L 31.168700,11.952000 L 31.678500,11.622900 L 31.678500,12.281100 L 32.768300,12.527200 L 33.858100,11.622900 L 33.931300,11.210800 L 34.875600,10.553100 C 34.533800,10.595600 34.192000,10.626800 33.858000,10.717700 L 33.858000,9.9766000 L 34.221300,9.1538000 L 33.858000,9.1538000 L 33.059600,9.8940000 L 32.840800,10.305600 L 33.059600,10.882300 L 32.695300,11.868600 L 32.114200,11.539500 L 31.606400,10.964300 L 30.805600,11.539500 L 30.514600,10.223600 L 31.895500,9.3188000 L 31.895500,8.8247000 L 32.768500,8.2490000 L 34.149400,7.9194000 L 35.094700,8.2490000 L 36.838800,8.5781000 L 36.403300,9.0713000 L 35.458000,9.0713000 L 36.403300,10.058600 L 37.129900,9.2363000 L 37.350600,8.8745000 C 37.350600,8.8745000 40.137700,11.372500 41.730500,14.105000 C 43.323300,16.838400 44.071300,20.060100 44.071300,20.714400 z "
id="path4144" />
</g>
</g>
<g
id="g4146">
<g
id="g4150">
<path
d="M 26.070300,9.2363000 L 25.997100,9.7295000 L 26.506900,10.058600 L 27.378000,9.4829000 L 26.942500,8.9892000 L 26.360500,9.3188000 L 26.070500,9.2363000"
id="path4152" />
</g>
</g>
<g
id="g4154">
<g
id="g4158">
<path
d="M 26.870100,5.8633000 L 24.979500,5.1226000 L 22.799800,5.3692000 L 20.109400,6.1094000 L 19.600600,6.6035000 L 21.272500,7.7549000 L 21.272500,8.4131000 L 20.618200,9.0713000 L 21.491200,10.800300 L 22.071300,10.470200 L 22.799800,9.3188000 C 23.922800,8.9716000 24.929700,8.5781000 25.997100,8.0844000 L 26.870100,5.8632000"
id="path4160" />
</g>
</g>
<g
id="g4162">
<g
id="g4166">
<path
d="M 28.833000,12.774900 L 28.542000,12.033700 L 28.032200,12.198700 L 28.178700,13.103000 L 28.833000,12.774900"
id="path4168" />
</g>
</g>
<g
id="g4170">
<g
id="g4174">
<path
d="M 29.123000,12.608900 L 28.977500,13.597200 L 29.777300,13.432200 L 30.358400,12.857000 L 29.849600,12.362900 C 29.678700,11.907800 29.482400,11.483000 29.268500,11.046500 L 28.833000,11.046500 L 28.833000,11.539700 L 29.123000,11.868800 L 29.123000,12.609000"
id="path4176" />
</g>
</g>
<g
id="g4178">
<g
id="g4182">
<path
d="M 18.365200,28.242200 L 17.783200,27.089900 L 16.692900,26.843300 L 16.111400,25.280800 L 14.657800,25.444900 L 13.422400,24.540600 L 12.113300,25.692000 L 12.113300,25.873600 C 11.717300,25.759300 11.230500,25.743700 10.877900,25.526900 L 10.586900,24.704600 L 10.586900,23.799300 L 9.7148000,23.881300 C 9.7876000,23.305100 9.8598000,22.729900 9.9331000,22.153800 L 9.4238000,22.153800 L 8.9155000,22.812000 L 8.4062000,23.058100 L 7.6791000,22.647900 L 7.6063000,21.742600 L 7.7518000,20.755300 L 8.8426000,19.933000 L 9.7147000,19.933000 L 9.8597000,19.438900 L 10.950000,19.685000 L 11.749800,20.673300 L 11.895300,19.026800 L 13.276600,17.875400 L 13.785400,16.641000 L 14.803000,16.229900 L 15.384500,15.407600 L 16.692600,15.159600 L 17.347400,14.173300 C 16.693100,14.173300 16.038800,14.173300 15.384500,14.173300 L 16.620300,13.597100 L 17.491900,13.597100 L 18.728200,13.185000 L 18.873700,12.692800 L 18.437200,12.280700 L 17.928400,12.115700 L 18.073900,11.622500 L 17.710600,10.882300 L 16.838000,11.210400 L 16.983500,10.552700 L 15.965900,9.9765000 L 15.166600,11.374400 L 15.238900,11.868500 L 14.439600,12.198600 L 13.930300,13.267900 L 13.712500,12.280600 L 12.331200,11.704400 L 12.112900,10.964200 L 13.930300,9.8939000 L 14.730100,9.1537000 L 14.802900,8.2489000 L 14.366900,8.0018000 L 13.785400,7.9193000 L 13.422100,8.8246000 C 13.422100,8.8246000 12.814200,8.9437000 12.657900,8.9823000 C 10.661800,10.821700 6.6286000,14.792400 5.6916000,22.288500 C 5.7287000,22.462300 6.3708000,23.470100 6.3708000,23.470100 L 7.8972000,24.374400 L 9.4236000,24.786500 L 10.078400,25.609700 L 11.095500,26.349900 L 11.677000,26.267900 L 12.113000,26.464200 L 12.113000,26.597000 L 11.531900,28.160000 L 11.095400,28.818200 L 11.240900,29.148300 L 10.877600,30.380700 L 12.186200,32.767400 L 13.494300,33.919700 L 14.076300,34.742000 L 14.003100,36.470500 L 14.439600,37.456800 L 14.003100,39.349400 C 14.003100,39.349400 13.968900,39.337700 14.024600,39.527100 C 14.080800,39.716600 16.353700,40.978300 16.498200,40.870900 C 16.642200,40.761500 16.765300,40.665800 16.765300,40.665800 L 16.620300,40.255600 L 17.201400,39.679400 L 17.419700,39.103200 L 18.365000,38.773100 L 19.091600,36.962600 L 18.873800,36.470400 L 19.381600,35.730200 L 20.472400,35.482200 L 21.054400,34.165800 L 20.908900,32.521300 L 21.781000,31.286900 L 21.926500,30.052500 C 20.733100,29.460700 19.549500,28.851300 18.365000,28.242000"
id="path4184" />
</g>
</g>
<g
id="g4186">
<g
id="g4190">
<path
d="M 16.765600,9.5649000 L 17.492200,10.058600 L 18.074200,10.058600 L 18.074200,9.4829000 L 17.347600,9.1538000 L 16.765600,9.5649000"
id="path4192" />
</g>
</g>
<g
id="g4194">
<g
id="g4198">
<path
d="M 14.876000,8.9072000 L 14.512200,9.8120000 L 15.239300,9.8120000 L 15.603100,8.9892000 C 15.916600,8.7675000 16.228600,8.5444000 16.547900,8.3310000 L 17.275000,8.5781000 C 17.759400,8.9072000 18.243800,9.2363000 18.728600,9.5649000 L 19.456100,8.9072000 L 18.655800,8.5781000 L 18.292000,7.8374000 L 16.911100,7.6728000 L 16.838300,7.2612000 L 16.184000,7.4262000 L 15.893600,8.0020000 L 15.529800,7.2613000 L 15.384800,7.5904000 L 15.457600,8.4132000 L 14.876000,8.9072000"
id="path4200" />
</g>
</g>
<g
id="g4202">
<g
style="opacity:0.75000000"
id="g4204">
<path
id="path4206"
d="" />
</g>
<g
id="g4208">
<path
id="path4210"
d="" />
</g>
</g>
<g
id="g4212">
<g
style="opacity:0.75000000"
id="g4214">
<path
id="path4216"
d="" />
</g>
<g
id="g4218">
<path
id="path4220"
d="" />
</g>
</g>
<g
id="g4222">
<g
id="g4226">
<path
d="M 17.492200,6.8496000 L 17.856000,6.5210000 L 18.583100,6.3564000 C 19.081100,6.1142000 19.581100,5.9511000 20.109500,5.7802000 L 19.819500,5.2865000 L 18.881000,5.4213000 L 18.437600,5.8632000 L 17.706600,5.9692000 L 17.056700,6.2744000 L 16.740800,6.4272000 L 16.547900,6.6855000 L 17.492200,6.8496000"
id="path4228" />
</g>
</g>
<g
id="g4230">
<g
id="g4234">
<path
d="M 18.728500,14.666500 L 19.165000,14.008300 L 18.510200,13.515100 L 18.728500,14.666500"
id="path4236" />
</g>
</g>
</g>
<g
id="g3216"
style="color:#000000;fill:url(#radialGradient1460);fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.0179454;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:inline;overflow:visible"
transform="matrix(0.982371,0.000000,0.000000,0.982371,-8.095179e-2,3.088300e-2)">
<g
id="g3218"
style="color:#000000;fill:url(#radialGradient1462);stroke-dashoffset:0.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:inline;overflow:visible">
<g
id="g3222"
style="color:#000000;fill:url(#radialGradient1466);stroke-dashoffset:0.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:inline;overflow:visible">
<path
d="M 44.071300,20.714400 C 44.071300,20.977100 44.071300,20.714400 44.071300,20.714400 L 43.526400,21.331600 C 43.192400,20.938000 42.817400,20.607000 42.436600,20.261300 L 41.600700,20.384300 L 40.837000,19.521000 L 40.837000,20.589400 L 41.491300,21.084500 L 41.926800,21.577700 L 42.508800,20.919500 C 42.655300,21.193900 42.799800,21.468300 42.945300,21.742700 L 42.945300,22.565000 L 42.290000,23.305200 L 41.090800,24.128400 L 40.182600,25.034700 L 39.600600,24.374500 L 39.891600,23.634300 L 39.310500,22.976100 L 38.329100,20.878400 L 37.493200,19.933100 L 37.274400,20.179200 L 37.602500,21.372600 L 38.219700,22.071800 C 38.572200,23.089400 38.920900,24.062000 39.383800,25.034700 C 40.101600,25.034700 40.778300,24.958500 41.491200,24.868700 L 41.491200,25.444900 L 40.619100,27.584100 L 39.819300,28.488400 L 39.165000,29.888800 C 39.165000,30.656400 39.165000,31.424000 39.165000,32.191500 L 39.383800,33.097800 L 39.020500,33.508000 L 38.219700,34.002100 L 37.383800,34.701300 L 38.075200,35.482600 L 37.129900,36.306800 L 37.311500,36.840000 L 35.893500,38.445500 L 34.949200,38.445500 L 34.149400,38.939600 L 33.639600,38.939600 L 33.639600,38.281400 L 33.422800,36.963000 C 33.141500,36.136800 32.848600,35.316500 32.550700,34.496200 C 32.550700,33.890700 32.586800,33.291100 32.623000,32.685700 L 32.987300,31.863400 L 32.477500,30.875100 L 32.514600,29.517700 L 31.823200,28.736400 L 32.168900,27.605500 L 31.606400,26.967300 L 30.624000,26.967300 L 30.296900,26.597200 L 29.315500,27.214900 L 28.916100,26.761300 L 28.006900,27.543000 C 27.389700,26.843300 26.771500,26.144100 26.153400,25.444900 L 25.426800,23.716400 L 26.081100,22.730100 L 25.717800,22.319000 L 26.516600,20.425400 C 27.172900,19.609000 27.858400,18.825800 28.551800,18.039700 L 29.788100,17.710600 L 31.169000,17.546500 L 32.114300,17.793600 L 33.459000,19.150000 L 33.931700,18.615800 L 34.585000,18.533800 L 35.821300,18.944900 L 36.766600,18.944900 L 37.420900,18.368700 L 37.711900,17.957600 L 37.056600,17.546500 L 35.965800,17.464500 C 35.663100,17.044600 35.381800,16.603200 35.022400,16.230100 L 34.658100,16.394200 L 34.512600,17.464500 L 33.858300,16.724300 L 33.713800,15.900100 L 32.987200,15.325900 L 32.695200,15.325900 L 33.422700,16.148200 L 33.131700,16.888400 L 32.550600,17.052500 L 32.913900,16.312300 L 32.258600,15.984200 L 31.678500,15.326000 L 30.586700,15.572100 L 30.442200,15.900200 L 29.787900,16.312300 L 29.424600,17.217600 L 28.516400,17.669700 L 28.116000,17.217600 L 27.680500,17.217600 L 27.680500,15.736200 L 28.625800,15.242100 L 29.352400,15.242100 L 29.205900,14.666900 L 28.625800,14.090700 L 29.606300,13.884600 L 30.151200,13.268400 L 30.586700,12.527200 L 31.387500,12.527200 L 31.168700,11.952000 L 31.678500,11.622900 L 31.678500,12.281100 L 32.768300,12.527200 L 33.858100,11.622900 L 33.931300,11.210800 L 34.875600,10.553100 C 34.533800,10.595600 34.192000,10.626800 33.858000,10.717700 L 33.858000,9.9766000 L 34.221300,9.1538000 L 33.858000,9.1538000 L 33.059600,9.8940000 L 32.840800,10.305600 L 33.059600,10.882300 L 32.695300,11.868600 L 32.114200,11.539500 L 31.606400,10.964300 L 30.805600,11.539500 L 30.514600,10.223600 L 31.895500,9.3188000 L 31.895500,8.8247000 L 32.768500,8.2490000 L 34.149400,7.9194000 L 35.094700,8.2490000 L 36.838800,8.5781000 L 36.403300,9.0713000 L 35.458000,9.0713000 L 36.403300,10.058600 L 37.129900,9.2363000 L 37.350600,8.8745000 C 37.350600,8.8745000 40.137700,11.372500 41.730500,14.105000 C 43.323300,16.838400 44.071300,20.060100 44.071300,20.714400 z "
id="path3224"
style="color:#000000;fill:url(#radialGradient1468);stroke-dashoffset:0.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:inline;overflow:visible" />
</g>
</g>
<g
id="g3226"
style="color:#000000;fill:url(#radialGradient1470);stroke-dashoffset:0.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:inline;overflow:visible">
<g
id="g3230"
style="color:#000000;fill:url(#radialGradient1474);stroke-dashoffset:0.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:inline;overflow:visible">
<path
d="M 26.070300,9.2363000 L 25.997100,9.7295000 L 26.506900,10.058600 L 27.378000,9.4829000 L 26.942500,8.9892000 L 26.360500,9.3188000 L 26.070500,9.2363000"
id="path3232"
style="color:#000000;fill:url(#radialGradient1476);stroke-dashoffset:0.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:inline;overflow:visible" />
</g>
</g>
<g
id="g3234"
style="color:#000000;fill:url(#radialGradient1478);stroke-dashoffset:0.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:inline;overflow:visible">
<g
id="g3238"
style="color:#000000;fill:url(#radialGradient1482);stroke-dashoffset:0.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:inline;overflow:visible">
<path
d="M 26.870100,5.8633000 L 24.979500,5.1226000 L 22.799800,5.3692000 L 20.109400,6.1094000 L 19.600600,6.6035000 L 21.272500,7.7549000 L 21.272500,8.4131000 L 20.618200,9.0713000 L 21.491200,10.800300 L 22.071300,10.470200 L 22.799800,9.3188000 C 23.922800,8.9716000 24.929700,8.5781000 25.997100,8.0844000 L 26.870100,5.8632000"
id="path3240"
style="color:#000000;fill:url(#radialGradient1484);stroke-dashoffset:0.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:inline;overflow:visible" />
</g>
</g>
<g
id="g3242"
style="color:#000000;fill:url(#radialGradient1486);stroke-dashoffset:0.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:inline;overflow:visible">
<g
id="g3246"
style="color:#000000;fill:url(#radialGradient1490);stroke-dashoffset:0.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:inline;overflow:visible">
<path
d="M 28.833000,12.774900 L 28.542000,12.033700 L 28.032200,12.198700 L 28.178700,13.103000 L 28.833000,12.774900"
id="path3248"
style="color:#000000;fill:url(#radialGradient1492);stroke-dashoffset:0.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:inline;overflow:visible" />
</g>
</g>
<g
id="g3250"
style="color:#000000;fill:url(#radialGradient1494);stroke-dashoffset:0.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:inline;overflow:visible">
<g
id="g3254"
style="color:#000000;fill:url(#radialGradient1498);stroke-dashoffset:0.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:inline;overflow:visible">
<path
d="M 29.123000,12.608900 L 28.977500,13.597200 L 29.777300,13.432200 L 30.358400,12.857000 L 29.849600,12.362900 C 29.678700,11.907800 29.482400,11.483000 29.268500,11.046500 L 28.833000,11.046500 L 28.833000,11.539700 L 29.123000,11.868800 L 29.123000,12.609000"
id="path3256"
style="color:#000000;fill:url(#radialGradient1500);stroke-dashoffset:0.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:inline;overflow:visible" />
</g>
</g>
<g
id="g3258"
style="color:#000000;fill:url(#radialGradient1502);stroke-dashoffset:0.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:inline;overflow:visible">
<g
id="g3262"
style="color:#000000;fill:url(#radialGradient1506);stroke-dashoffset:0.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:inline;overflow:visible">
<path
d="M 18.365200,28.242200 L 17.783200,27.089900 L 16.692900,26.843300 L 16.111400,25.280800 L 14.657800,25.444900 L 13.422400,24.540600 L 12.113300,25.692000 L 12.113300,25.873600 C 11.717300,25.759300 11.230500,25.743700 10.877900,25.526900 L 10.586900,24.704600 L 10.586900,23.799300 L 9.7148000,23.881300 C 9.7876000,23.305100 9.8598000,22.729900 9.9331000,22.153800 L 9.4238000,22.153800 L 8.9155000,22.812000 L 8.4062000,23.058100 L 7.6791000,22.647900 L 7.6063000,21.742600 L 7.7518000,20.755300 L 8.8426000,19.933000 L 9.7147000,19.933000 L 9.8597000,19.438900 L 10.950000,19.685000 L 11.749800,20.673300 L 11.895300,19.026800 L 13.276600,17.875400 L 13.785400,16.641000 L 14.803000,16.229900 L 15.384500,15.407600 L 16.692600,15.159600 L 17.347400,14.173300 C 16.693100,14.173300 16.038800,14.173300 15.384500,14.173300 L 16.620300,13.597100 L 17.491900,13.597100 L 18.728200,13.185000 L 18.873700,12.692800 L 18.437200,12.280700 L 17.928400,12.115700 L 18.073900,11.622500 L 17.710600,10.882300 L 16.838000,11.210400 L 16.983500,10.552700 L 15.965900,9.9765000 L 15.166600,11.374400 L 15.238900,11.868500 L 14.439600,12.198600 L 13.930300,13.267900 L 13.712500,12.280600 L 12.331200,11.704400 L 12.112900,10.964200 L 13.930300,9.8939000 L 14.730100,9.1537000 L 14.802900,8.2489000 L 14.366900,8.0018000 L 13.785400,7.9193000 L 13.422100,8.8246000 C 13.422100,8.8246000 12.814200,8.9437000 12.657900,8.9823000 C 10.661800,10.821700 6.6286000,14.792400 5.6916000,22.288500 C 5.7287000,22.462300 6.3708000,23.470100 6.3708000,23.470100 L 7.8972000,24.374400 L 9.4236000,24.786500 L 10.078400,25.609700 L 11.095500,26.349900 L 11.677000,26.267900 L 12.113000,26.464200 L 12.113000,26.597000 L 11.531900,28.160000 L 11.095400,28.818200 L 11.240900,29.148300 L 10.877600,30.380700 L 12.186200,32.767400 L 13.494300,33.919700 L 14.076300,34.742000 L 14.003100,36.470500 L 14.439600,37.456800 L 14.003100,39.349400 C 14.003100,39.349400 13.968900,39.337700 14.024600,39.527100 C 14.080800,39.716600 16.353700,40.978300 16.498200,40.870900 C 16.642200,40.761500 16.765300,40.665800 16.765300,40.665800 L 16.620300,40.255600 L 17.201400,39.679400 L 17.419700,39.103200 L 18.365000,38.773100 L 19.091600,36.962600 L 18.873800,36.470400 L 19.381600,35.730200 L 20.472400,35.482200 L 21.054400,34.165800 L 20.908900,32.521300 L 21.781000,31.286900 L 21.926500,30.052500 C 20.733100,29.460700 19.549500,28.851300 18.365000,28.242000"
id="path3264"
style="color:#000000;fill:url(#radialGradient1508);stroke-dashoffset:0.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:inline;overflow:visible" />
</g>
</g>
<g
id="g3266"
style="color:#000000;fill:url(#radialGradient1510);stroke-dashoffset:0.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:inline;overflow:visible">
<g
id="g3270"
style="color:#000000;fill:url(#radialGradient1514);stroke-dashoffset:0.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:inline;overflow:visible">
<path
d="M 16.765600,9.5649000 L 17.492200,10.058600 L 18.074200,10.058600 L 18.074200,9.4829000 L 17.347600,9.1538000 L 16.765600,9.5649000"
id="path3272"
style="color:#000000;fill:url(#radialGradient1516);stroke-dashoffset:0.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:inline;overflow:visible" />
</g>
</g>
<g
id="g3274"
style="color:#000000;fill:url(#radialGradient1518);stroke-dashoffset:0.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:inline;overflow:visible">
<g
id="g3278"
style="color:#000000;fill:url(#radialGradient1522);stroke-dashoffset:0.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:inline;overflow:visible">
<path
d="M 14.876000,8.9072000 L 14.512200,9.8120000 L 15.239300,9.8120000 L 15.603100,8.9892000 C 15.916600,8.7675000 16.228600,8.5444000 16.547900,8.3310000 L 17.275000,8.5781000 C 17.759400,8.9072000 18.243800,9.2363000 18.728600,9.5649000 L 19.456100,8.9072000 L 18.655800,8.5781000 L 18.292000,7.8374000 L 16.911100,7.6728000 L 16.838300,7.2612000 L 16.184000,7.4262000 L 15.893600,8.0020000 L 15.529800,7.2613000 L 15.384800,7.5904000 L 15.457600,8.4132000 L 14.876000,8.9072000"
id="path3280"
style="color:#000000;fill:url(#radialGradient1524);stroke-dashoffset:0.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:inline;overflow:visible" />
</g>
</g>
<g
id="g3282"
style="color:#000000;fill:url(#radialGradient1526);stroke-dashoffset:0.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:inline;overflow:visible">
<g
style="opacity:0.75000000;color:#000000;fill:url(#radialGradient1528);stroke-dashoffset:0.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:inline;overflow:visible"
id="g3284">
<path
d=""
style="color:#000000;fill:url(#radialGradient1530);stroke-dashoffset:0.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:inline;overflow:visible"
id="path3286" />
</g>
<g
id="g3288"
style="color:#000000;fill:url(#radialGradient1532);stroke-dashoffset:0.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:inline;overflow:visible">
<path
d=""
id="path3290"
style="color:#000000;fill:url(#radialGradient1534);stroke-dashoffset:0.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:inline;overflow:visible" />
</g>
</g>
<g
id="g3292"
style="color:#000000;fill:url(#radialGradient1536);stroke-dashoffset:0.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:inline;overflow:visible">
<g
style="opacity:0.75000000;color:#000000;fill:url(#radialGradient1538);stroke-dashoffset:0.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:inline;overflow:visible"
id="g3294">
<path
d=""
style="color:#000000;fill:url(#radialGradient1540);stroke-dashoffset:0.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:inline;overflow:visible"
id="path3296" />
</g>
<g
id="g3298"
style="color:#000000;fill:url(#radialGradient1542);stroke-dashoffset:0.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:inline;overflow:visible">
<path
d=""
id="path3300"
style="color:#000000;fill:url(#radialGradient1544);stroke-dashoffset:0.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:inline;overflow:visible" />
</g>
</g>
<g
id="g3302"
style="color:#000000;fill:url(#radialGradient1546);stroke-dashoffset:0.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:inline;overflow:visible">
<g
id="g3306"
style="color:#000000;fill:url(#radialGradient1550);stroke-dashoffset:0.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:inline;overflow:visible">
<path
d="M 17.492200,6.8496000 L 17.856000,6.5210000 L 18.583100,6.3564000 C 19.081100,6.1142000 19.581100,5.9511000 20.109500,5.7802000 L 19.819500,5.2865000 L 18.881000,5.4213000 L 18.437600,5.8632000 L 17.706600,5.9692000 L 17.056700,6.2744000 L 16.740800,6.4272000 L 16.547900,6.6855000 L 17.492200,6.8496000"
id="path3308"
style="color:#000000;fill:url(#radialGradient1552);stroke-dashoffset:0.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:inline;overflow:visible" />
</g>
</g>
<g
id="g3310"
style="color:#000000;fill:url(#radialGradient1554);stroke-dashoffset:0.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:inline;overflow:visible">
<g
id="g3314"
style="color:#000000;fill:url(#radialGradient1558);stroke-dashoffset:0.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:inline;overflow:visible">
<path
d="M 18.728500,14.666500 L 19.165000,14.008300 L 18.510200,13.515100 L 18.728500,14.666500"
id="path3316"
style="color:#000000;fill:url(#radialGradient4756);stroke-dashoffset:0.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:inline;overflow:visible" />
</g>
</g>
</g>
<path
style="fill:none;fill-opacity:1.0000000;fill-rule:nonzero;stroke:url(#radialGradient4132);stroke-miterlimit:4.0000000;stroke-opacity:1.0000000"
d="M 42.975093,23.485534 C 42.975093,33.651354 34.733915,41.892440 24.569493,41.892440 C 14.404139,41.892440 6.1634261,33.651261 6.1634261,23.485534 C 6.1634261,13.320180 14.404139,5.0799340 24.569493,5.0799340 C 34.733915,5.0799340 42.975093,13.320180 42.975093,23.485534 L 42.975093,23.485534 z "
id="path4122" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 49 KiB

View File

@ -53,7 +53,9 @@
<file>window-new.svg</file>
<file>camera-photo.svg</file>
<file>applications-accessories.svg</file>
<file>applications-python.svg</file>
<file>accessories-text-editor.svg</file>
<file>internet-web-browser.svg</file>
<file>view-unselectable.svg</file>
<file>view-refresh.svg</file>
<file>view-fullscreen.svg</file>

View File

@ -407,10 +407,11 @@ StdCmdPythonHelp::StdCmdPythonHelp()
: Command("Std_PythonHelp"), server(0)
{
sGroup = QT_TR_NOOP("Tools");
sMenuText = QT_TR_NOOP("Python Modules");
sToolTipText = QT_TR_NOOP("Opens a browser to show the Python modules");
sWhatsThis = QT_TR_NOOP("Opens a browser to show the Python modules");
sStatusTip = QT_TR_NOOP("Opens a browser to show the Python modules");
sMenuText = QT_TR_NOOP("Automatic python modules documentation");
sToolTipText = QT_TR_NOOP("Opens a browser to show the Python modules documentation");
sWhatsThis = QT_TR_NOOP("Opens a browser to show the Python modules documentation");
sStatusTip = QT_TR_NOOP("Opens a browser to show the Python modules documentation");
sPixmap = "applications-python";
}
StdCmdPythonHelp::~StdCmdPythonHelp()

View File

@ -71,7 +71,7 @@ const char* TouchpadNavigationStyle::mouseButtons(ViewerMode mode)
case NavigationStyle::DRAGGING:
return QT_TR_NOOP("Press ALT button");
case NavigationStyle::ZOOMING:
return QT_TR_NOOP("Press PgUp/PgDown button");
return QT_TR_NOOP("Press CTRL and SHIFT buttons");
default:
return "No description";
}
@ -310,12 +310,12 @@ SbBool TouchpadNavigationStyle::processSoEvent(const SoEvent * const ev)
newmode = NavigationStyle::PANNING;
break;
case ALTDOWN:
case CTRLDOWN|SHIFTDOWN:
if (newmode != NavigationStyle::DRAGGING) {
saveCursorPosition(ev);
}
newmode = NavigationStyle::DRAGGING;
break;
case CTRLDOWN|SHIFTDOWN:
case CTRLDOWN|SHIFTDOWN|BUTTON1DOWN:
newmode = NavigationStyle::ZOOMING;
break;

View File

@ -681,10 +681,14 @@ bool View3DInventor::onHasMsg(const char* pMsg) const
return true;
else if (strcmp("SaveAs",pMsg) == 0)
return true;
else if (strcmp("Undo",pMsg) == 0)
return getAppDocument() && getAppDocument()->getAvailableUndos() > 0;
else if (strcmp("Redo",pMsg) == 0)
return getAppDocument() && getAppDocument()->getAvailableRedos() > 0;
else if (strcmp("Undo",pMsg) == 0) {
App::Document* doc = getAppDocument();
return doc && doc->getAvailableUndos() > 0;
}
else if (strcmp("Redo",pMsg) == 0) {
App::Document* doc = getAppDocument();
return doc && doc->getAvailableRedos() > 0;
}
else if (strcmp("Print",pMsg) == 0)
return true;
else if (strcmp("PrintPreview",pMsg) == 0)

View File

@ -449,9 +449,9 @@ MenuItem* StdWorkbench::setupMenuBar() const
MenuItem* stdviews = new MenuItem;
stdviews->setCommand("Standard views");
*stdviews << "Std_ViewFitAll" << "Std_ViewFitSelection" << "Std_ViewAxo"
<< "Separator" << "Std_ViewFront" << "Std_ViewRight"
<< "Std_ViewTop" << "Separator" << "Std_ViewRear"
<< "Std_ViewLeft" << "Std_ViewBottom"
<< "Separator" << "Std_ViewFront" << "Std_ViewTop"
<< "Std_ViewRight" << "Separator" << "Std_ViewRear"
<< "Std_ViewBottom" << "Std_ViewLeft"
<< "Separator" << "Std_ViewRotateLeft" << "Std_ViewRotateRight";
// stereo
@ -514,15 +514,12 @@ MenuItem* StdWorkbench::setupMenuBar() const
sep->setCommand( "Separator" );
// Help
MenuItem* helpWebsites = new MenuItem;
helpWebsites->setCommand("&On-line help");
*helpWebsites << "Std_OnlineHelpWebsite" << "Std_FreeCADWebsite" << "Std_PythonWebsite";
MenuItem* help = new MenuItem( menuBar );
help->setCommand("&Help");
*help << "Std_OnlineHelp" << "Std_PythonHelp"
<< helpWebsites << "Separator" << "Std_About"
<< "Std_AboutQt" << "Separator" << "Std_WhatsThis";
*help << "Std_OnlineHelp" << "Std_FreeCADWebsite"
<< "Std_FreeCADUserHub" << "Std_FreeCADPowerUserHub"
<< "Std_PythonHelp" << "Std_FreeCADForum"
<< "Std_FreeCADFAQ" << "Std_About" << "Std_WhatsThis";
return menuBar;
}
@ -547,9 +544,9 @@ ToolBarItem* StdWorkbench::setupToolBars() const
// View
ToolBarItem* view = new ToolBarItem( root );
view->setCommand("View");
*view << "Std_ViewFitAll" << "Separator" << "Std_ViewAxo" << "Separator" << "Std_ViewFront"
<< "Std_ViewRight" << "Std_ViewTop" << "Separator" << "Std_ViewRear" << "Std_ViewLeft"
<< "Std_ViewBottom" << "Separator" << "Std_MeasureDistance" ;
*view << "Std_ViewFitAll" << "Separator" << "Std_ViewAxo" << "Separator" << "Std_ViewFront"
<< "Std_ViewTop" << "Std_ViewRight" << "Separator" << "Std_ViewRear" << "Std_ViewBottom"
<< "Std_ViewLeft" << "Separator" << "Std_MeasureDistance" ;
return root;
}

View File

@ -36,7 +36,7 @@ using namespace Gui::PropertyEditor;
PropertyItemDelegate::PropertyItemDelegate(QObject* parent)
: QItemDelegate(parent)
: QItemDelegate(parent), pressed(false)
{
}
@ -89,6 +89,16 @@ void PropertyItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &
painter->setPen(savedPen);
}
bool PropertyItemDelegate::editorEvent (QEvent * event, QAbstractItemModel* model,
const QStyleOptionViewItem& option, const QModelIndex& index)
{
if (event && event->type() == QEvent::MouseButtonPress)
this->pressed = true;
else
this->pressed = false;
return QItemDelegate::editorEvent(event, model, option, index);
}
QWidget * PropertyItemDelegate::createEditor (QWidget * parent, const QStyleOptionViewItem & /*option*/,
const QModelIndex & index ) const
{
@ -101,6 +111,9 @@ QWidget * PropertyItemDelegate::createEditor (QWidget * parent, const QStyleOpti
QWidget* editor = childItem->createEditor(parent, this, SLOT(valueChanged()));
if (editor && childItem->isReadOnly())
editor->setDisabled(true);
else if (editor && this->pressed)
editor->setFocus();
this->pressed = false;
return editor;
}

View File

@ -42,9 +42,14 @@ public:
virtual void setEditorData(QWidget *editor, const QModelIndex &index) const;
virtual void setModelData (QWidget *editor, QAbstractItemModel *model, const QModelIndex& index ) const;
virtual QSize sizeHint(const QStyleOptionViewItem & option, const QModelIndex & index) const;
virtual bool editorEvent (QEvent *event, QAbstractItemModel *model,
const QStyleOptionViewItem& option, const QModelIndex& index);
public Q_SLOTS:
void valueChanged();
private:
mutable bool pressed;
};
} // namespace PropertyEditor

View File

@ -39,3 +39,4 @@ from ArchSectionPlane import *
from ArchWindow import *
from ArchAxis import *
from ArchRoof import *
from ArchSpace import *

View File

@ -67,25 +67,24 @@ def addComponents(objectsList,host):
example to add windows to a wall, or to add walls to a cell or floor.'''
if not isinstance(objectsList,list):
objectsList = [objectsList]
tp = Draft.getType(host)
if tp in ["Cell"]:
c = host.Components
for o in objectsList:
if not o in c:
c.append(o)
host.Components = c
elif tp in ["Floor","Building","Site"]:
hostType = Draft.getType(host)
if hostType in ["Floor","Building","Site"]:
c = host.Group
for o in objectsList:
if not o in c:
c.append(o)
host.Group = c
elif tp in ["Wall","Structure","Window","Roof"]:
elif hostType in ["Wall","Structure","Window","Roof"]:
import DraftGeomUtils
a = host.Additions
if hasattr(host,"Axes"):
x = host.Axes
for o in objectsList:
if Draft.getType(o) == "Axis":
if DraftGeomUtils.isValidPath(o.Shape) and (hostType == "Structure"):
if o.Support == host:
o.Support = None
host.Tool = o
elif Draft.getType(o) == "Axis":
if not o in x:
x.append(o)
elif not o in a:
@ -94,7 +93,7 @@ def addComponents(objectsList,host):
host.Additions = a
if hasattr(host,"Axes"):
host.Axes = x
elif tp in ["SectionPlane"]:
elif hostType in ["SectionPlane"]:
a = host.Objects
for o in objectsList:
if not o in a:
@ -117,6 +116,9 @@ def removeComponents(objectsList,host=None):
objectsList = [objectsList]
if host:
if Draft.getType(host) in ["Wall","Structure"]:
if hasattr(host,"Tool"):
if objectsList[0] == host.Tool:
host.Tool = None
if hasattr(host,"Axes"):
a = host.Axes
for o in objectsList[:]:
@ -150,7 +152,7 @@ def removeComponents(objectsList,host=None):
if o.InList:
h = o.InList[0]
tp = Draft.getType(h)
if tp in ["Cell","Floor","Building","Site"]:
if tp in ["Floor","Building","Site"]:
c = h.Components
if o in c:
c.remove(o)
@ -271,8 +273,8 @@ def makeFace(wires,method=2,cleanup=False):
#print "makeFace: reversing",w
w.reverse()
# make sure that the exterior wires comes as first in the list
wires.insert(0, ext)
#print "makeFace: done sorting", wires
wires.insert(0, ext)
#print "makeFace: done sorting", wires
if wires:
return Part.Face(wires)
else:
@ -317,17 +319,29 @@ def getCutVolume(cutplane,shapes):
"""getCutVolume(cutplane,shapes): returns a cut face and a cut volume
from the given shapes and the given cutting plane"""
import Part
placement = FreeCAD.Placement(cutplane.Placement)
if not isinstance(shapes,list):
shapes = [shapes]
# building boundbox
bb = shapes[0].BoundBox
bb = shapes[0].BoundBox
for sh in shapes[1:]:
bb.add(sh.BoundBox)
bb.enlarge(1)
# building cutplane space
placement = None
um = vm = wm = 0
ax = placement.Rotation.multVec(FreeCAD.Vector(0,0,1))
u = placement.Rotation.multVec(FreeCAD.Vector(1,0,0))
v = placement.Rotation.multVec(FreeCAD.Vector(0,1,0))
if not bb.isCutPlane(placement.Base,ax):
try:
if hasattr(cutplane,"Shape"):
p = cutplane.Shape.copy().Faces[0]
else:
p = cutplane.copy().Faces[0]
except:
FreeCAD.Console.PrintMessage(str(translate("Arch","Invalid cutplane")))
return None,None,None
ce = p.CenterOfMass
ax = p.normalAt(0,0)
u = p.Vertexes[1].Point.sub(p.Vertexes[0].Point).normalize()
v = u.cross(ax)
if not bb.isCutPlane(ce,ax):
FreeCAD.Console.PrintMessage(str(translate("Arch","No objects are cut by the plane")))
return None,None,None
else:
@ -340,23 +354,26 @@ def getCutVolume(cutplane,shapes):
FreeCAD.Vector(bb.XMax,bb.YMin,bb.ZMax),
FreeCAD.Vector(bb.XMax,bb.YMax,bb.ZMax)]
for c in corners:
dv = c.sub(placement.Base)
dv = c.sub(ce)
um1 = DraftVecUtils.project(dv,u).Length
um = max(um,um1)
vm1 = DraftVecUtils.project(dv,v).Length
vm = max(vm,vm1)
wm1 = DraftVecUtils.project(dv,ax).Length
wm = max(wm,wm1)
p1 = FreeCAD.Vector(-um,vm,0)
p2 = FreeCAD.Vector(um,vm,0)
p3 = FreeCAD.Vector(um,-vm,0)
p4 = FreeCAD.Vector(-um,-vm,0)
vu = DraftVecUtils.scaleTo(u,um)
vui = vu.negative()
vv = DraftVecUtils.scaleTo(v,vm)
vvi = vv.negative()
p1 = ce.add(vu.add(vvi))
p2 = ce.add(vu.add(vv))
p3 = ce.add(vui.add(vv))
p4 = ce.add(vui.add(vvi))
cutface = Part.makePolygon([p1,p2,p3,p4,p1])
cutface = Part.Face(cutface)
cutface.Placement = placement
cutnormal = DraftVecUtils.scaleTo(ax,wm)
cutvolume = cutface.extrude(cutnormal)
cutnormal = DraftVecUtils.neg(cutnormal)
cutnormal = cutnormal.negative()
invcutvolume = cutface.extrude(cutnormal)
return cutface,cutvolume,invcutvolume
@ -442,7 +459,7 @@ def removeShape(objs,mark=True):
length = dims[1]
width = dims[2]
v1 = Vector(length/2,0,0)
v2 = DraftVecUtils.neg(v1)
v2 = v1.negative()
v1 = dims[0].multVec(v1)
v2 = dims[0].multVec(v2)
line = Draft.makeLine(v1,v2)
@ -556,17 +573,22 @@ class _CommandAdd:
def Activated(self):
sel = FreeCADGui.Selection.getSelection()
FreeCAD.ActiveDocument.openTransaction(str(translate("Arch","Grouping")))
if not mergeCells(sel):
host = sel.pop()
ss = "["
for o in sel:
if len(ss) > 1:
ss += ","
ss += "FreeCAD.ActiveDocument."+o.Name
ss += "]"
if Draft.getType(sel[-1]) == "Space":
FreeCAD.ActiveDocument.openTransaction(str(translate("Arch","Add space boundary")))
FreeCADGui.doCommand("import Arch")
FreeCADGui.doCommand("Arch.addComponents("+ss+",FreeCAD.ActiveDocument."+host.Name+")")
FreeCADGui.doCommand("Arch.addSpaceBoundaries( FreeCAD.ActiveDocument."+sel[-1].Name+", FreeCADGui.Selection.getSelectionEx() )")
else:
FreeCAD.ActiveDocument.openTransaction(str(translate("Arch","Grouping")))
if not mergeCells(sel):
host = sel.pop()
ss = "["
for o in sel:
if len(ss) > 1:
ss += ","
ss += "FreeCAD.ActiveDocument."+o.Name
ss += "]"
FreeCADGui.doCommand("import Arch")
FreeCADGui.doCommand("Arch.addComponents("+ss+",FreeCAD.ActiveDocument."+host.Name+")")
FreeCAD.ActiveDocument.commitTransaction()
FreeCAD.ActiveDocument.recompute()
@ -586,20 +608,25 @@ class _CommandRemove:
def Activated(self):
sel = FreeCADGui.Selection.getSelection()
FreeCAD.ActiveDocument.openTransaction(str(translate("Arch","Ungrouping")))
if (Draft.getType(sel[-1]) in ["Wall","Structure"]) and (len(sel) > 1):
host = sel.pop()
ss = "["
for o in sel:
if len(ss) > 1:
ss += ","
ss += "FreeCAD.ActiveDocument."+o.Name
ss += "]"
if Draft.getType(sel[-1]) == "Space":
FreeCAD.ActiveDocument.openTransaction(str(translate("Arch","Remove space boundary")))
FreeCADGui.doCommand("import Arch")
FreeCADGui.doCommand("Arch.removeComponents("+ss+",FreeCAD.ActiveDocument."+host.Name+")")
FreeCADGui.doCommand("Arch.removeSpaceBoundaries( FreeCAD.ActiveDocument."+sel[-1].Name+", FreeCADGui.Selection.getSelection() )")
else:
FreeCADGui.doCommand("import Arch")
FreeCADGui.doCommand("Arch.removeComponents(Arch.ActiveDocument."+sel[-1].Name+")")
FreeCAD.ActiveDocument.openTransaction(str(translate("Arch","Ungrouping")))
if (Draft.getType(sel[-1]) in ["Wall","Structure"]) and (len(sel) > 1):
host = sel.pop()
ss = "["
for o in sel:
if len(ss) > 1:
ss += ","
ss += "FreeCAD.ActiveDocument."+o.Name
ss += "]"
FreeCADGui.doCommand("import Arch")
FreeCADGui.doCommand("Arch.removeComponents("+ss+",FreeCAD.ActiveDocument."+host.Name+")")
else:
FreeCADGui.doCommand("import Arch")
FreeCADGui.doCommand("Arch.removeComponents(Arch.ActiveDocument."+sel[-1].Name+")")
FreeCAD.ActiveDocument.commitTransaction()
FreeCAD.ActiveDocument.recompute()

View File

@ -26,6 +26,7 @@ __author__ = "Yorik van Havre"
__url__ = "http://free-cad.sourceforge.net"
import FreeCAD,FreeCADGui,Draft
from FreeCAD import Vector
from PyQt4 import QtGui,QtCore
from DraftTools import translate
@ -104,6 +105,22 @@ def removeFromComponent(compobject,subobject):
compobject.Subtractions = l
if Draft.getType(subobject) != "Window":
subobject.ViewObject.hide()
class SelectionTaskPanel:
"""A temp taks panel to wait for a selection"""
def __init__(self):
self.form = QtGui.QLabel()
self.form.setText(QtGui.QApplication.translate("Arch", "Please select a base object", None, QtGui.QApplication.UnicodeUTF8))
def getStandardButtons(self):
return int(QtGui.QDialogButtonBox.Cancel)
def reject(self):
if hasattr(FreeCAD,"ArchObserver"):
FreeCADGui.Selection.removeObserver(FreeCAD.ArchObserver)
del FreeCAD.ArchObserver
return True
class ComponentTaskPanel:
@ -270,11 +287,12 @@ class Component:
self.Type = "Component"
self.Subvolume = None
def execute(self,obj):
return
def __getstate__(self):
return self.Type
def __setstate__(self,state):
if state:
self.Type = state
@ -307,8 +325,8 @@ class Component:
n = f.normalAt(0,0)
v1 = DraftVecUtils.scaleTo(n,width*1.1) # we extrude a little more to avoid face-on-face
f.translate(v1)
v2 = DraftVecUtils.neg(v1)
v2 = DraftVecUtils.scale(v1,-2)
v2 = v1.negative()
v2 = Vector(v1).multiply(-2)
f = f.extrude(v2)
if plac:
f.Placement = plac
@ -408,7 +426,7 @@ class ViewProviderComponent:
vobj.Proxy = self
self.Object = vobj.Object
def updateData(self,vobj,prop):
def updateData(self,obj,prop):
return
def onChanged(self,vobj,prop):
@ -443,10 +461,15 @@ class ViewProviderComponent:
return None
def claimChildren(self):
c = [self.Object.Base]+self.Object.Additions+self.Object.Subtractions
if hasattr(self.Object,"Fixtures"):
c.extend(self.Object.Fixtures)
return c
if hasattr(self,"Object"):
c = [self.Object.Base]+self.Object.Additions+self.Object.Subtractions
if hasattr(self.Object,"Fixtures"):
c.extend(self.Object.Fixtures)
if hasattr(self.Object,"Tool"):
if self.Object.Tool:
c.append(self.Object.Tool)
return c
return []
def setEdit(self,vobj,mode):
taskd = ComponentTaskPanel()
@ -460,18 +483,32 @@ class ViewProviderComponent:
return False
class ArchSelectionObserver:
def __init__(self,origin,watched,hide=True,nextCommand=None):
"""ArchSelectionObserver([origin,watched,hide,nextCommand]): The ArchSelectionObserver
object can be added as a selection observer to the FreeCAD Gui. If watched is given (a
document object), the observer will be triggered only when that object is selected/unselected.
If hide is True, the watched object will be hidden. If origin is given (a document
object), that object will have its visibility/selectability restored. If nextCommand
is given (a FreeCAD command), it will be executed on leave."""
def __init__(self,origin=None,watched=None,hide=True,nextCommand=None):
self.origin = origin
self.watched = watched
self.hide = hide
self.nextCommand = nextCommand
def addSelection(self,document, object, element, position):
if object == self.watched.Name:
if not self.watched:
FreeCADGui.Selection.removeObserver(FreeCAD.ArchObserver)
if self.nextCommand:
FreeCADGui.runCommand(self.nextCommand)
del FreeCAD.ArchObserver
elif object == self.watched.Name:
if not element:
FreeCAD.Console.PrintMessage(str(translate("Arch","closing Sketch edit")))
if self.hide:
self.origin.ViewObject.Transparency = 0
self.origin.ViewObject.Selectable = True
if self.origin:
self.origin.ViewObject.Transparency = 0
self.origin.ViewObject.Selectable = True
self.watched.ViewObject.hide()
FreeCADGui.activateWorkbench("ArchWorkbench")
FreeCADGui.Selection.removeObserver(FreeCAD.ArchObserver)

View File

@ -52,17 +52,12 @@ class _CommandRoof:
'Accel': "R, F",
'ToolTip': QtCore.QT_TRANSLATE_NOOP("Arch_Roof","Creates a roof object from the selected face of an object")}
def IsActive(self):
if FreeCADGui.Selection.getSelection():
return True
else:
return False
def Activated(self):
sel = FreeCADGui.Selection.getSelectionEx()
if sel:
sel = sel[0]
obj = sel.Object
FreeCADGui.Control.closeDialog()
if sel.HasSubObjects:
if "Face" in sel.SubElementNames[0]:
idx = int(sel.SubElementNames[0][4:])
@ -83,7 +78,10 @@ class _CommandRoof:
else:
FreeCAD.Console.PrintMessage(str(translate("Arch","Unable to create a roof")))
else:
FreeCAD.Console.PrintMessage(str(translate("Arch","No object selected")))
FreeCAD.Console.PrintMessage(str(translate("Arch","Please select a base object\n")))
FreeCADGui.Control.showDialog(ArchComponent.SelectionTaskPanel())
FreeCAD.ArchObserver = ArchComponent.ArchSelectionObserver(nextCommand="Arch_Roof")
FreeCADGui.Selection.addObserver(FreeCAD.ArchObserver)
class _Roof(ArchComponent.Component):
"The Roof object"

288
src/Mod/Arch/ArchSpace.py Normal file
View File

@ -0,0 +1,288 @@
#***************************************************************************
#* *
#* Copyright (c) 2013 *
#* Yorik van Havre <yorik@uncreated.net> *
#* *
#* 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. *
#* *
#* This program 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 program; if not, write to the Free Software *
#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
#* USA *
#* *
#***************************************************************************
import FreeCAD,FreeCADGui,ArchComponent,ArchCommands,math,Draft
from DraftTools import translate
from PyQt4 import QtCore
def makeSpace(objects=None):
"""makeSpace([objects]): Creates a space object from the given objects. Objects can be one
document object, in which case it becomes the base shape of the space object, or a list of
selection objects as got from getSelectionEx(), or a list of tuples (object, subobjectname)"""
obj = FreeCAD.ActiveDocument.addObject("Part::FeaturePython","Space")
_Space(obj)
_ViewProviderSpace(obj.ViewObject)
if objects:
if not isinstance(objects,list):
objects = [objects]
if len(objects) == 1:
obj.Base = objects[0]
objects[0].ViewObject.hide()
else:
obj.Proxy.addSubobjects(obj,objects)
def addSpaceBoundaries(space,subobjects):
"""addSpaceBoundaries(space,subobjects): adds the given subobjects to the given space"""
import Draft
if Draft.getType(space) == "Space":
space.Proxy.addSubobjects(space,subobjects)
def removeSpaceBoundaries(space,objects):
"""removeSpaceBoundaries(space,objects): removes the given objects from the given spaces boundaries"""
import Draft
if Draft.getType(space) == "Space":
bounds = space.Boundaries
for o in objects:
for b in bounds:
if o.Name == b[0].Name:
bounds.remove(b)
break
space.Boundaries = bounds
class _CommandSpace:
"the Arch Space command definition"
def GetResources(self):
return {'Pixmap' : 'Arch_Space',
'MenuText': QtCore.QT_TRANSLATE_NOOP("Arch_Space","Space"),
'Accel': "S, P",
'ToolTip': QtCore.QT_TRANSLATE_NOOP("Arch_Space","Creates a space object from selected boundary objects")}
def Activated(self):
FreeCAD.ActiveDocument.openTransaction(str(translate("Arch","Create Space")))
FreeCADGui.doCommand("import Arch")
sel = FreeCADGui.Selection.getSelection()
if sel:
FreeCADGui.Control.closeDialog()
if len(sel) == 1:
FreeCADGui.doCommand("Arch.makeSpace(FreeCADGui.Selection.getSelection())")
else:
FreeCADGui.doCommand("Arch.makeSpace(FreeCADGui.Selection.getSelectionEx())")
FreeCAD.ActiveDocument.commitTransaction()
FreeCAD.ActiveDocument.recompute()
else:
FreeCAD.Console.PrintMessage(str(translate("Arch","Please select a base object\n")))
FreeCADGui.Control.showDialog(ArchComponent.SelectionTaskPanel())
FreeCAD.ArchObserver = ArchComponent.ArchSelectionObserver(nextCommand="Arch_Space")
FreeCADGui.Selection.addObserver(FreeCAD.ArchObserver)
class _Space(ArchComponent.Component):
"A space object"
def __init__(self,obj):
obj.Proxy = self
obj.addProperty("App::PropertyLink","Base","Base",
str(translate("Arch","A base shape defining this space")))
obj.addProperty("App::PropertyLinkSubList","Boundaries","Base",
str(translate("Arch","The objects that make the boundaries of this space object")))
self.Type = "Space"
def execute(self,obj):
self.getShape(obj)
def onChanged(self,obj,prop):
if prop in ["Boundaries","Base"]:
self.getShape(obj)
def addSubobjects(self,obj,subobjects):
"adds subobjects to this space"
objs = obj.Boundaries
for o in subobjects:
if isinstance(o,tuple) or isinstance(o,list):
if o[0].Name != obj.Name:
objs.append(tuple(o))
else:
for el in o.SubElementNames:
if "Face" in el:
if o.Object.Name != obj.Name:
objs.append((o.Object,el))
obj.Boundaries = objs
def getShape(self,obj):
"computes a shape from a base shape and/or bounday faces"
import Part
shape = None
faces = []
#print "starting compute"
# 1: if we have a base shape, we use it
if obj.Base:
if obj.Base.isDerivedFrom("Part::Feature"):
if obj.Base.Shape.Solids:
shape = obj.Base.Shape.Solids[0].copy()
# 2: if not, add all bounding boxes of considered objects and build a first shape
if shape:
#print "got shape from base object"
bb = shape.BoundBox
else:
bb = None
for b in obj.Boundaries:
if b[0].isDerivedFrom("Part::Feature"):
if not bb:
bb = b[0].Shape.BoundBox
else:
bb.add(b[0].Shape.BoundBox)
if not bb:
return
shape = Part.makeBox(bb.XLength,bb.YLength,bb.ZLength,FreeCAD.Vector(bb.XMin,bb.YMin,bb.ZMin))
#print "created shape from boundbox"
# 3: identifing boundary faces
goodfaces = []
for b in obj.Boundaries:
if b[0].isDerivedFrom("Part::Feature"):
if "Face" in b[1]:
fn = int(b[1][4:])-1
faces.append(b[0].Shape.Faces[fn])
#print "adding face ",fn," of object ",b[0].Name
#print "total: ", len(faces), " faces"
# 4: get cutvolumes from faces
cutvolumes = []
for f in faces:
f = f.copy()
f.reverse()
cutface,cutvolume,invcutvolume = ArchCommands.getCutVolume(f,shape)
if cutvolume:
#print "generated 1 cutvolume"
cutvolumes.append(cutvolume.copy())
#Part.show(cutvolume)
for v in cutvolumes:
#print "cutting"
shape = shape.cut(v)
# 5: get the final shape
if shape:
if shape.Solids:
#print "setting objects shape"
shape = shape.Solids[0]
obj.Shape = shape
return
print "Arch: error computing space boundary"
def getArea(self,obj):
"returns the horizontal area at the center of the space"
import Part,DraftGeomUtils
try:
pl = Part.makePlane(1,1)
sh = obj.Shape.copy()
cutplane,v1,v2 = ArchCommands.getCutVolume(pl,sh)
e = sh.section(cutplane)
e = DraftGeomUtils.sortEdges(e.Edges)
w = Part.Wire(e)
f = Part.Face(w)
return round(f.Area,Draft.getParam("dimPrecision"))
except:
return 0
class _ViewProviderSpace(ArchComponent.ViewProviderComponent):
"A View Provider for Section Planes"
def __init__(self,vobj):
vobj.Transparency = 85
vobj.LineWidth = 1
vobj.LineColor = (1.0,0.0,0.0,1.0)
vobj.DrawStyle = "Dotted"
vobj.addProperty("App::PropertyString","Override","Base",
"Text override. Use $area to insert the area")
vobj.addProperty("App::PropertyColor","TextColor","Base",
"The color of the area text")
vobj.TextColor = (1.0,0.0,0.0,1.0)
vobj.Override = "$area m2"
ArchComponent.ViewProviderComponent.__init__(self,vobj)
def getIcon(self):
import Arch_rc
return ":/icons/Arch_Space_Tree.svg"
def claimChildren(self):
if self.Object.Base:
return [self.Object.Base]
else:
return []
def setDisplayMode(self,mode):
if mode == "Detailed":
self.setAnnotation(True)
return "Flat Lines"
else:
self.setAnnotation(False)
return mode
def getArea(self,obj):
"returns a formatted area text"
area = str(obj.Proxy.getArea(obj))
if obj.ViewObject.Override:
text = obj.ViewObject.Override
area = text.replace("$area",str(area))
return str(area)
def setAnnotation(self,recreate=True):
if hasattr(self,"Object"):
if hasattr(self,"area"):
if self.area:
self.Object.ViewObject.Annotation.removeChild(self.area)
self.area = None
self.coords = None
self.anno = None
if recreate:
area = self.getArea(self.Object)
if area:
from pivy import coin
import SketcherGui
self.area = coin.SoSeparator()
self.coords = coin.SoTransform()
if self.Object.Shape:
if not self.Object.Shape.isNull():
c = self.Object.Shape.CenterOfMass
self.coords.translation.setValue([c.x,c.y,c.z])
self.anno = coin.SoType.fromName("SoDatumLabel").createInstance()
self.anno.string.setValue(area)
self.anno.datumtype.setValue(6)
color = coin.SbVec3f(self.Object.ViewObject.TextColor[:3])
self.anno.textColor.setValue(color)
self.area.addChild(self.coords)
self.area.addChild(self.anno)
self.Object.ViewObject.Annotation.addChild(self.area)
def updateData(self,obj,prop):
if prop == "Shape":
if hasattr(self,"area"):
if self.area:
area = self.getArea(obj)
self.anno.string.setValue(area)
if not obj.Shape.isNull():
c = obj.Shape.CenterOfMass
self.coords.translation.setValue([c.x,c.y,c.z])
def onChanged(self,vobj,prop):
if prop in ["Override","TextColor"]:
if vobj.DisplayMode == "Detailed":
self.setAnnotation(True)
return
FreeCADGui.addCommand('Arch_Space',_CommandSpace())

View File

@ -30,7 +30,80 @@ __title__="FreeCAD Structure"
__author__ = "Yorik van Havre"
__url__ = "http://free-cad.sourceforge.net"
def makeStructure(baseobj=None,length=1,width=1,height=1,name=str(translate("Arch","Structure"))):
# Make some strings picked by the translator
QtCore.QT_TRANSLATE_NOOP("Arch","Wood")
QtCore.QT_TRANSLATE_NOOP("Arch","Steel")
# Presets in the form: Class, Name, Width, Height, [Web thickness, Flange thickness]
Presets = [None,
# wood sections
["Wood","1x2in",19,28],
["Wood","1x3in",19,64],
["Wood","1x4in",19,89],
["Wood","1x6in",19,89],
["Wood","1x8in",19,140],
["Wood","1x10in",19,184],
["Wood","1x12in",19,286],
["Wood","2x2in",38,38],
["Wood","2x3in",38,64],
["Wood","2x4in",38,89],
["Wood","2x6in",38,140],
["Wood","2x8in",38,184],
["Wood","2x10in",38,235],
["Wood","2x12in",38,286],
["Wood","4x4in",89,89],
["Wood","4x6in",89,140],
["Wood","6x6in",140,140],
["Wood","8x8in",184,184],
# IPE beams
["Steel","IPE90",46,80,3.8,5.2],
["Steel","IPE100",55,100,4.1,5.7],
["Steel","IPE120",64,120,4.4,6.3],
["Steel","IPE140",73,140,4.7,6.9],
["Steel","IPE160",82,160,5,7.4],
["Steel","IPE180",91,180,5.3,8],
["Steel","IPE200",100,200,5.6,8.5],
["Steel","IPE220",110,220,5.9,9.2],
["Steel","IPE240",120,240,6.2,9.8],
["Steel","IPE270",135,270,6.6,10.2],
["Steel","IPE300",150,300,7.1,10.7],
["Steel","IPE330",160,330,7.5,11.5],
["Steel","IPE360",170,360,8,12.7],
["Steel","IPE400",180,400,8.6,13.5],
["Steel","IPE450",190,450,9.4,14.6],
["Steel","IPE500",200,500,10.2,16],
["Steel","IPE550",210,550,11.1,17.2],
["Steel","IPE600",220,600,12,19],
# INP beams
["Steel","INP80",42,80,3.9,5.9],
["Steel","INP100",50,100,4.5,6.8],
["Steel","INP120",58,120,5.1,7.7],
["Steel","INP140",66,140,5.7,8.6],
["Steel","INP160",74,160,6.3,9.5],
["Steel","INP180",82,180,6.9,10.4],
["Steel","INP200",90,200,7.5,11.3],
["Steel","INP220",98,220,8.1,12.2],
["Steel","INP240",106,240,8.7,13.1],
["Steel","INP260",113,260,9.4,14.1],
["Steel","INP280",119,280,10.1,15.2],
["Steel","INP300",125,300,10.8,16.2],
["Steel","INP320",131,320,11.5,17.3],
["Steel","INP340",137,340,12.2,18.3],
["Steel","INP360",143,360,13,19.5],
["Steel","INP380",149,380,13.7,20.5],
["Steel","INP400",155,400,14.4,21.6]
]
def makeStructure(baseobj=None,length=0,width=0,height=0,name=str(translate("Arch","Structure"))):
'''makeStructure([obj],[length],[width],[heigth],[swap]): creates a
structure element based on the given profile object and the given
extrusion height. If no base object is given, you can also specify
@ -41,9 +114,12 @@ def makeStructure(baseobj=None,length=1,width=1,height=1,name=str(translate("Arc
if baseobj:
obj.Base = baseobj
obj.Base.ViewObject.hide()
obj.Width = width
obj.Height = height
obj.Length = length
if width:
obj.Width = width
if height:
obj.Height = height
if length:
obj.Length = length
obj.ViewObject.ShapeColor = ArchCommands.getDefaultColor("Structure")
return obj
@ -58,6 +134,21 @@ def makeStructuralSystem(objects,axes):
result.append(s)
FreeCAD.ActiveDocument.recompute()
return result
def makeProfile(W=46,H=80,tw=3.8,tf=5.2):
'''makeProfile(W,H,tw,tf): returns a shape with one face describing
the profile of a steel beam (IPE, IPN, HE, etc...) based on the following
dimensions: W = total width, H = total height, tw = web thickness
tw = flange thickness (see http://en.wikipedia.org/wiki/I-beam for
reference)'''
obj = FreeCAD.ActiveDocument.addObject("Part::Part2DObjectPython","Profile")
_Profile(obj)
obj.Width = W
obj.Height = H
obj.WebThickness = tw
obj.FlangeThickness = tf
Draft._ViewProviderDraft(obj.ViewObject)
return obj
class _CommandStructure:
"the Arch Structure command definition"
@ -72,9 +163,11 @@ class _CommandStructure:
global QtGui, QtCore
from PyQt4 import QtGui, QtCore
self.Length = 0.5
self.Width = 0.2
self.Height = 1
p = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Arch")
self.Length = p.GetFloat("StructureLength",100)
self.Width = p.GetFloat("StructureWidth",100)
self.Height = p.GetFloat("StructureHeight",1000)
self.Profile = 0
self.continueCmd = False
sel = FreeCADGui.Selection.getSelection()
if sel:
@ -94,6 +187,8 @@ class _CommandStructure:
FreeCAD.ActiveDocument.recompute()
else:
# interactive mode
if hasattr(FreeCAD,"DraftWorkingPlane"):
FreeCAD.DraftWorkingPlane.setup()
import DraftTrackers
self.points = []
self.tracker = DraftTrackers.boxTracker()
@ -110,7 +205,18 @@ class _CommandStructure:
return
FreeCAD.ActiveDocument.openTransaction(str(translate("Arch","Create Structure")))
FreeCADGui.doCommand('import Arch')
FreeCADGui.doCommand('s = Arch.makeStructure(length='+str(self.Length)+',width='+str(self.Width)+',height='+str(self.Height)+')')
if self.Profile:
pr = Presets[self.Profile]
FreeCADGui.doCommand('p = Arch.makeProfile('+str(pr[2])+','+str(pr[3])+','+str(pr[4])+','+str(pr[5])+')')
if self.Length == pr[2]:
# vertical
FreeCADGui.doCommand('s = Arch.makeStructure(p,height='+str(self.Height)+')')
else:
# horizontal
FreeCADGui.doCommand('s = Arch.makeStructure(p,height='+str(self.Length)+')')
FreeCADGui.doCommand('s.Placement.Rotation = FreeCAD.Rotation(-0.5,0.5,-0.5,0.5)')
else:
FreeCADGui.doCommand('s = Arch.makeStructure(length='+str(self.Length)+',width='+str(self.Width)+',height='+str(self.Height)+')')
FreeCADGui.doCommand('s.Placement.Base = '+DraftVecUtils.toString(point))
FreeCAD.ActiveDocument.commitTransaction()
FreeCAD.ActiveDocument.recompute()
@ -123,45 +229,74 @@ class _CommandStructure:
w.setWindowTitle(str(translate("Arch","Structure options")))
lay0 = QtGui.QVBoxLayout(w)
# presets box
layp = QtGui.QHBoxLayout()
lay0.addLayout(layp)
labelp = QtGui.QLabel(str(translate("Arch","Preset")))
layp.addWidget(labelp)
valuep = QtGui.QComboBox()
fpresets = [" "]
for p in Presets[1:]:
fpresets.append(str(translate("Arch",p[0]))+" "+p[1]+" ("+str(p[2])+"x"+str(p[3])+"mm)")
valuep.addItems(fpresets)
layp.addWidget(valuep)
# length
lay1 = QtGui.QHBoxLayout()
lay0.addLayout(lay1)
label1 = QtGui.QLabel(str(translate("Arch","Length")))
lay1.addWidget(label1)
value1 = QtGui.QDoubleSpinBox()
value1.setDecimals(2)
value1.setValue(self.Length)
lay1.addWidget(value1)
self.vLength = QtGui.QDoubleSpinBox()
self.vLength.setDecimals(2)
self.vLength.setMaximum(99999.99)
self.vLength.setValue(self.Length)
lay1.addWidget(self.vLength)
# width
lay2 = QtGui.QHBoxLayout()
lay0.addLayout(lay2)
label2 = QtGui.QLabel(str(translate("Arch","Width")))
lay2.addWidget(label2)
value2 = QtGui.QDoubleSpinBox()
value2.setDecimals(2)
value2.setValue(self.Width)
lay2.addWidget(value2)
self.vWidth = QtGui.QDoubleSpinBox()
self.vWidth.setDecimals(2)
self.vWidth.setMaximum(99999.99)
self.vWidth.setValue(self.Width)
lay2.addWidget(self.vWidth)
# height
lay3 = QtGui.QHBoxLayout()
lay0.addLayout(lay3)
label3 = QtGui.QLabel(str(translate("Arch","Height")))
lay3.addWidget(label3)
value3 = QtGui.QDoubleSpinBox()
value3.setDecimals(2)
value3.setValue(self.Height)
lay3.addWidget(value3)
self.vHeight = QtGui.QDoubleSpinBox()
self.vHeight.setDecimals(2)
self.vHeight.setMaximum(99999.99)
self.vHeight.setValue(self.Height)
lay3.addWidget(self.vHeight)
# horizontal button
value5 = QtGui.QPushButton(str(translate("Arch","Rotate")))
lay0.addWidget(value5)
# continue button
value4 = QtGui.QCheckBox(str(translate("Arch","Continue")))
lay0.addWidget(value4)
QtCore.QObject.connect(value1,QtCore.SIGNAL("valueChanged(double)"),self.setLength)
QtCore.QObject.connect(value2,QtCore.SIGNAL("valueChanged(double)"),self.setWidth)
QtCore.QObject.connect(value3,QtCore.SIGNAL("valueChanged(double)"),self.setHeight)
QtCore.QObject.connect(valuep,QtCore.SIGNAL("currentIndexChanged(int)"),self.setPreset)
QtCore.QObject.connect(self.vLength,QtCore.SIGNAL("valueChanged(double)"),self.setLength)
QtCore.QObject.connect(self.vWidth,QtCore.SIGNAL("valueChanged(double)"),self.setWidth)
QtCore.QObject.connect(self.vHeight,QtCore.SIGNAL("valueChanged(double)"),self.setHeight)
QtCore.QObject.connect(value4,QtCore.SIGNAL("stateChanged(int)"),self.setContinue)
QtCore.QObject.connect(value5,QtCore.SIGNAL("pressed()"),self.rotate)
return w
def update(self,point):
"this function is called by the Snapper when the mouse is moved"
self.tracker.pos(point)
if self.Height >= self.Length:
delta = Vector(0,0,self.Height/2)
else:
delta = Vector(self.Length/2,0,0)
self.tracker.pos(point.add(delta))
def setWidth(self,d):
self.Width = d
@ -177,11 +312,30 @@ class _CommandStructure:
def setContinue(self,i):
self.continueCmd = bool(i)
def setPreset(self,i):
if i > 0:
self.vLength.setValue(float(Presets[i][2]))
self.vWidth.setValue(float(Presets[i][3]))
if len(Presets[i]) == 6:
self.Profile = i
else:
self.Profile = 0
def rotate(self):
l = self.Length
w = self.Width
h = self.Height
self.vLength.setValue(h)
self.vHeight.setValue(w)
self.vWidth.setValue(l)
class _Structure(ArchComponent.Component):
"The Structure object"
def __init__(self,obj):
ArchComponent.Component.__init__(self,obj)
obj.addProperty("App::PropertyLink","Tool","Base",
"An optional extrusion path for this element")
obj.addProperty("App::PropertyLength","Length","Base",
str(translate("Arch","The length of this element, if not based on a profile")))
obj.addProperty("App::PropertyLength","Width","Base",
@ -195,13 +349,16 @@ class _Structure(ArchComponent.Component):
obj.addProperty("App::PropertyIntegerList","Exclude","Base",
str(translate("Arch","The element numbers to exclude when this structure is based on axes")))
self.Type = "Structure"
obj.Length = 1
obj.Width = 1
obj.Height = 1
def execute(self,obj):
self.createGeometry(obj)
def onChanged(self,obj,prop):
self.hideSubobjects(obj,prop)
if prop in ["Base","Length","Width","Height","Normal","Additions","Subtractions","Axes"]:
if prop in ["Base","Tool","Length","Width","Height","Normal","Additions","Subtractions","Axes"]:
self.createGeometry(obj)
def getAxisPoints(self,obj):
@ -245,21 +402,30 @@ class _Structure(ArchComponent.Component):
base = None
if obj.Base:
if obj.Base.isDerivedFrom("Part::Feature"):
if obj.Normal == Vector(0,0,0):
p = FreeCAD.Placement(obj.Base.Placement)
normal = p.Rotation.multVec(Vector(0,0,1))
else:
normal = Vector(obj.Normal)
normal = normal.multiply(height)
base = obj.Base.Shape.copy()
if base.Solids:
pass
elif base.Faces:
base = base.extrude(normal)
elif (len(base.Wires) == 1):
if base.Wires[0].isClosed():
base = Part.Face(base.Wires[0])
if hasattr(obj,"Tool"):
if obj.Tool:
try:
base = obj.Tool.Shape.copy().makePipe(obj.Base.Shape.copy())
except:
FreeCAD.Console.PrintError(str(translate("Arch","Error: The base shape couldn't be extruded along this tool object")))
return
if not base:
if obj.Normal == Vector(0,0,0):
p = FreeCAD.Placement(obj.Base.Placement)
normal = p.Rotation.multVec(Vector(0,0,1))
else:
normal = Vector(obj.Normal)
normal = normal.multiply(height)
base = obj.Base.Shape.copy()
if base.Solids:
pass
elif base.Faces:
base = base.extrude(normal)
elif (len(base.Wires) == 1):
if base.Wires[0].isClosed():
base = Part.Face(base.Wires[0])
base = base.extrude(normal)
elif obj.Base.isDerivedFrom("Mesh::Feature"):
if obj.Base.Mesh.isSolid():
if obj.Base.Mesh.countComponents() == 1:
@ -310,13 +476,14 @@ class _Structure(ArchComponent.Component):
if base.Volume < 0:
base.reverse()
if base.Volume < 0:
FreeCAD.Console.PrintError(str(translate("Arch","Couldn't compute the wall shape")))
FreeCAD.Console.PrintError(str(translate("Arch","Couldn't compute a shape")))
return
base = base.removeSplitter()
obj.Shape = base
if not DraftGeomUtils.isNull(pl):
obj.Placement = pl
class _ViewProviderStructure(ArchComponent.ViewProviderComponent):
"A View Provider for the Structure object"
@ -327,4 +494,43 @@ class _ViewProviderStructure(ArchComponent.ViewProviderComponent):
import Arch_rc
return ":/icons/Arch_Structure_Tree.svg"
class _Profile(Draft._DraftObject):
"A parametric beam profile object"
def __init__(self,obj):
obj.addProperty("App::PropertyDistance","Width","Base","Width of the beam").Width = 10
obj.addProperty("App::PropertyDistance","Height","Base","Height of the beam").Height = 30
obj.addProperty("App::PropertyDistance","WebThickness","Base","Thickness of the webs").WebThickness = 3
obj.addProperty("App::PropertyDistance","FlangeThickness","Base","Thickness of the flange").FlangeThickness = 2
Draft._DraftObject.__init__(self,obj,"Profile")
def execute(self,obj):
self.createGeometry(obj)
def onChanged(self,obj,prop):
if prop in ["Width","Height","WebThickness","FlangeThickness"]:
self.createGeometry(obj)
def createGeometry(self,obj):
import Part
pl = obj.Placement
p1 = Vector(-obj.Width/2,-obj.Height/2,0)
p2 = Vector(obj.Width/2,-obj.Height/2,0)
p3 = Vector(obj.Width/2,(-obj.Height/2)+obj.FlangeThickness,0)
p4 = Vector(obj.WebThickness/2,(-obj.Height/2)+obj.FlangeThickness,0)
p5 = Vector(obj.WebThickness/2,obj.Height/2-obj.FlangeThickness,0)
p6 = Vector(obj.Width/2,obj.Height/2-obj.FlangeThickness,0)
p7 = Vector(obj.Width/2,obj.Height/2,0)
p8 = Vector(-obj.Width/2,obj.Height/2,0)
p9 = Vector(-obj.Width/2,obj.Height/2-obj.FlangeThickness,0)
p10 = Vector(-obj.WebThickness/2,obj.Height/2-obj.FlangeThickness,0)
p11 = Vector(-obj.WebThickness/2,(-obj.Height/2)+obj.FlangeThickness,0)
p12 = Vector(-obj.Width/2,(-obj.Height/2)+obj.FlangeThickness,0)
p = Part.makePolygon([p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p1])
p = Part.Face(p)
obj.Shape = p
obj.Placement = pl
FreeCADGui.addCommand('Arch_Structure',_CommandStructure())

View File

@ -30,15 +30,18 @@ __title__="FreeCAD Wall"
__author__ = "Yorik van Havre"
__url__ = "http://free-cad.sourceforge.net"
def makeWall(baseobj=None,width=None,height=None,align="Center",name=str(translate("Arch","Wall"))):
'''makeWall(obj,[width],[height],[align],[name]): creates a wall based on the
given object, which can be a sketch, a draft object, a face or a solid. align
def makeWall(baseobj=None,length=None,width=None,height=None,align="Center",name=str(translate("Arch","Wall"))):
'''makeWall([obj],[length],[width],[height],[align],[name]): creates a wall based on the
given object, which can be a sketch, a draft object, a face or a solid, or no object at
all, then you must provide length, width and height. Align
can be "Center","Left" or "Right"'''
obj = FreeCAD.ActiveDocument.addObject("Part::FeaturePython",name)
_Wall(obj)
_ViewProviderWall(obj.ViewObject)
if baseobj:
obj.Base = baseobj
if length:
obj.Length = length
if width:
obj.Width = width
if height:
@ -95,7 +98,7 @@ def mergeShapes(w1,w2):
w = DraftGeomUtils.findWires(eds)
if len(w) == 1:
print "found common wire"
normal,width,height = w1.Proxy.getDefaultValues(w1)
normal,length,width,height = w1.Proxy.getDefaultValues(w1)
print w[0].Edges
sh = w1.Proxy.getBase(w1,w[0],normal,width,height)
print sh
@ -133,12 +136,12 @@ class _CommandWall:
global QtGui, QtCore
from PyQt4 import QtGui, QtCore
self.Width = 0.1
self.Height = 1
self.Align = "Center"
self.Length = None
self.continueCmd = False
p = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Arch")
self.Width = p.GetFloat("WallWidth",200)
self.Height = p.GetFloat("WallHeight",3000)
self.JOIN_WALLS = p.GetBool("joinWallSketches")
sel = FreeCADGui.Selection.getSelection()
done = False
@ -157,6 +160,8 @@ class _CommandWall:
import DraftTrackers
self.points = []
self.tracker = DraftTrackers.boxTracker()
if hasattr(FreeCAD,"DraftWorkingPlane"):
FreeCAD.DraftWorkingPlane.setup()
FreeCADGui.Snapper.getPoint(callback=self.getPoint,extradlg=self.taskbox())
def getPoint(self,point=None,obj=None):
@ -222,7 +227,7 @@ class _CommandWall:
elif self.Align == "Left":
self.tracker.update([b.add(dv),point.add(dv)])
else:
dv = DraftVecUtils.neg(dv)
dv = dv.negative()
self.tracker.update([b.add(dv),point.add(dv)])
if self.Length:
self.Length.setValue(bv.Length)
@ -328,6 +333,8 @@ class _Wall(ArchComponent.Component):
"The Wall object"
def __init__(self,obj):
ArchComponent.Component.__init__(self,obj)
obj.addProperty("App::PropertyLength","Length","Base",
str(translate("Arch","The length of this wall. Not used if this wall is based on an underlying object")))
obj.addProperty("App::PropertyLength","Width","Base",
str(translate("Arch","The width of this wall. Not used if this wall is based on a face")))
obj.addProperty("App::PropertyLength","Height","Base",
@ -341,8 +348,9 @@ class _Wall(ArchComponent.Component):
obj.Align = ['Left','Right','Center']
obj.ForceWire = False
self.Type = "Wall"
obj.Width = 0.1
obj.Height = 0
obj.Width = 1
obj.Height = 1
obj.Length = 1
def execute(self,obj):
self.createGeometry(obj)
@ -366,7 +374,11 @@ class _Wall(ArchComponent.Component):
def getDefaultValues(self,obj):
"returns normal,width,height values from this wall"
width = 1.0
length = 1
if hasattr(obj,"Length"):
if obj.Length:
length = obj.Length
width = 1
if hasattr(obj,"Width"):
if obj.Width:
width = obj.Width
@ -379,7 +391,7 @@ class _Wall(ArchComponent.Component):
if Draft.getType(p) == "Floor":
height = p.Height
if not height:
height = 1.0
height = 1
if hasattr(obj,"Normal"):
if obj.Normal == Vector(0,0,0):
normal = Vector(0,0,1)
@ -387,7 +399,7 @@ class _Wall(ArchComponent.Component):
normal = Vector(obj.Normal)
else:
normal = Vector(0,0,1)
return normal,width,height
return normal,length,width,height
def getBase(self,obj,wire,normal,width,height):
"returns a full shape from a base wire"
@ -399,20 +411,20 @@ class _Wall(ArchComponent.Component):
if not DraftVecUtils.isNull(dvec):
dvec.normalize()
if obj.Align == "Left":
dvec = dvec.multiply(width)
dvec.multiply(width)
w2 = DraftGeomUtils.offsetWire(wire,dvec)
w1 = Part.Wire(DraftGeomUtils.sortEdges(wire.Edges))
sh = DraftGeomUtils.bind(w1,w2)
elif obj.Align == "Right":
dvec = dvec.multiply(width)
dvec = DraftVecUtils.neg(dvec)
dvec.multiply(width)
dvec = dvec.negative()
w2 = DraftGeomUtils.offsetWire(wire,dvec)
w1 = Part.Wire(DraftGeomUtils.sortEdges(wire.Edges))
sh = DraftGeomUtils.bind(w1,w2)
elif obj.Align == "Center":
dvec = dvec.multiply(width/2)
dvec.multiply(width/2)
w1 = DraftGeomUtils.offsetWire(wire,dvec)
dvec = DraftVecUtils.neg(dvec)
dvec = dvec.negative()
w2 = DraftGeomUtils.offsetWire(wire,dvec)
sh = DraftGeomUtils.bind(w1,w2)
# fixing self-intersections
@ -425,54 +437,58 @@ class _Wall(ArchComponent.Component):
def createGeometry(self,obj):
"builds the wall shape"
if not obj.Base:
return
import Part, DraftGeomUtils
pl = obj.Placement
normal,width,height = self.getDefaultValues(obj)
# computing shape
normal,length,width,height = self.getDefaultValues(obj)
base = None
if obj.Base.isDerivedFrom("Part::Feature"):
if not obj.Base.Shape.isNull():
if obj.Base.Shape.isValid():
base = obj.Base.Shape.copy()
if base.Solids:
pass
elif (len(base.Faces) == 1) and (not obj.ForceWire):
if height:
norm = normal.multiply(height)
base = base.extrude(norm)
elif len(base.Wires) >= 1:
temp = None
for wire in obj.Base.Shape.Wires:
sh = self.getBase(obj,wire,normal,width,height)
if temp:
temp = temp.fuse(sh)
else:
temp = sh
base = temp
elif base.Edges:
wire = Part.Wire(base.Edges)
if wire:
sh = self.getBase(obj,wire,normal,width,height)
if sh:
base = sh
else:
base = None
FreeCAD.Console.PrintError(str(translate("Arch","Error: Invalid base object")))
elif obj.Base.isDerivedFrom("Mesh::Feature"):
if obj.Base.Mesh.isSolid():
if obj.Base.Mesh.countComponents() == 1:
sh = ArchCommands.getShapeFromMesh(obj.Base.Mesh)
if sh.isClosed() and sh.isValid() and sh.Solids and (not sh.isNull()):
base = sh
else:
FreeCAD.Console.PrintWarning(str(translate("Arch","This mesh is an invalid solid")))
obj.Base.ViewObject.show()
# computing a shape from scratch
if not obj.Base:
if length and width and height:
base = Part.makeBox(length,width,height)
else:
FreeCAD.Console.PrintError(str(translate("Arch","Error: Unable to compute a base shape")))
return
else:
# computing a shape from a base object
if obj.Base.isDerivedFrom("Part::Feature"):
if not obj.Base.Shape.isNull():
if obj.Base.Shape.isValid():
base = obj.Base.Shape.copy()
if base.Solids:
pass
elif (len(base.Faces) == 1) and (not obj.ForceWire):
if height:
normal.multiply(height)
base = base.extrude(normal)
elif len(base.Wires) >= 1:
temp = None
for wire in obj.Base.Shape.Wires:
sh = self.getBase(obj,wire,normal,width,height)
if temp:
temp = temp.fuse(sh)
else:
temp = sh
base = temp
elif base.Edges:
wire = Part.Wire(base.Edges)
if wire:
sh = self.getBase(obj,wire,normal,width,height)
if sh:
base = sh
else:
base = None
FreeCAD.Console.PrintError(str(translate("Arch","Error: Invalid base object")))
elif obj.Base.isDerivedFrom("Mesh::Feature"):
if obj.Base.Mesh.isSolid():
if obj.Base.Mesh.countComponents() == 1:
sh = ArchCommands.getShapeFromMesh(obj.Base.Mesh)
if sh.isClosed() and sh.isValid() and sh.Solids and (not sh.isNull()):
base = sh
else:
FreeCAD.Console.PrintWarning(str(translate("Arch","This mesh is an invalid solid")))
obj.Base.ViewObject.show()
base = self.processSubShapes(obj,base)

View File

@ -51,7 +51,7 @@ def makeWindow(baseobj=None,width=None,name=str(translate("Arch","Window"))):
if obj.Base:
obj.Base.ViewObject.DisplayMode = "Wireframe"
obj.Base.ViewObject.hide()
obj.ViewObject.ShapeColor = ArchCommands.getDefaultColor("Window")
#obj.ViewObject.ShapeColor = ArchCommands.getDefaultColor("Window")
return obj
def makeDefaultWindowPart(obj):
@ -77,38 +77,40 @@ class _CommandWindow:
'Accel': "W, N",
'ToolTip': QtCore.QT_TRANSLATE_NOOP("Arch_Window","Creates a window object from a selected object (wire, rectangle or sketch)")}
def IsActive(self):
if FreeCADGui.Selection.getSelection():
return True
else:
return False
def Activated(self):
sel = FreeCADGui.Selection.getSelection()
if sel:
if Draft.getType(sel[0]) == "Wall":
obj = sel[0]
if Draft.getType(obj) == "Wall":
FreeCADGui.activateWorkbench("SketcherWorkbench")
FreeCADGui.runCommand("Sketcher_NewSketch")
FreeCAD.ArchObserver = ArchComponent.ArchSelectionObserver(sel[0],FreeCAD.ActiveDocument.Objects[-1],hide=False,nextCommand="Arch_Window")
FreeCAD.ArchObserver = ArchComponent.ArchSelectionObserver(obj,FreeCAD.ActiveDocument.Objects[-1],hide=False,nextCommand="Arch_Window")
FreeCADGui.Selection.addObserver(FreeCAD.ArchObserver)
else:
FreeCADGui.Control.closeDialog()
FreeCAD.ActiveDocument.openTransaction(str(translate("Arch","Create Window")))
FreeCADGui.doCommand("import Arch")
for obj in sel:
FreeCADGui.doCommand("Arch.makeWindow(FreeCAD.ActiveDocument."+obj.Name+")")
if hasattr(obj,"Support"):
if obj.Support:
if isinstance(obj.Support,tuple):
s = obj.Support[0]
else:
s = obj.Support
w = FreeCAD.ActiveDocument.Objects[-1] # last created object
FreeCADGui.doCommand("Arch.removeComponents(FreeCAD.ActiveDocument."+w.Name+",host=FreeCAD.ActiveDocument."+s.Name+")")
elif Draft.isClone(obj,"Window"):
if obj.Objects[0].Inlist:
FreeCADGui.doCommand("Arch.removeComponents(FreeCAD.ActiveDocument."+obj.Name+",host=FreeCAD.ActiveDocument."+obj.Objects[0].Inlist[0].Name+")")
FreeCADGui.doCommand("Arch.makeWindow(FreeCAD.ActiveDocument."+obj.Name+")")
if hasattr(obj,"Support"):
if obj.Support:
if isinstance(obj.Support,tuple):
s = obj.Support[0]
else:
s = obj.Support
w = FreeCAD.ActiveDocument.Objects[-1] # last created object
FreeCADGui.doCommand("Arch.removeComponents(FreeCAD.ActiveDocument."+w.Name+",host=FreeCAD.ActiveDocument."+s.Name+")")
elif Draft.isClone(obj,"Window"):
if obj.Objects[0].Inlist:
FreeCADGui.doCommand("Arch.removeComponents(FreeCAD.ActiveDocument."+obj.Name+",host=FreeCAD.ActiveDocument."+obj.Objects[0].Inlist[0].Name+")")
FreeCAD.ActiveDocument.commitTransaction()
FreeCAD.ActiveDocument.recompute()
else:
FreeCAD.Console.PrintMessage(str(translate("Arch","Please select a base object\n")))
FreeCADGui.Control.showDialog(ArchComponent.SelectionTaskPanel())
FreeCAD.ArchObserver = ArchComponent.ArchSelectionObserver(nextCommand="Arch_Window")
FreeCADGui.Selection.addObserver(FreeCAD.ArchObserver)
class _Window(ArchComponent.Component):
"The Window object"
def __init__(self,obj):
@ -122,6 +124,7 @@ class _Window(ArchComponent.Component):
self.createGeometry(obj)
def onChanged(self,obj,prop):
print prop
self.hideSubobjects(obj,prop)
if prop in ["Base","WindowParts"]:
self.createGeometry(obj)
@ -170,6 +173,11 @@ class _Window(ArchComponent.Component):
base = Part.makeCompound(shapes)
if not DraftGeomUtils.isNull(pl):
base.Placement = pl
elif not obj.WindowParts:
# create default parts
obj.WindowParts = makeDefaultWindowPart(obj.Base)
else:
print "Arch: Bad formatting of window parts definitions"
base = self.processSubShapes(obj,base)
if base:
@ -188,12 +196,16 @@ class _ViewProviderWindow(ArchComponent.ViewProviderComponent):
def updateData(self,obj,prop):
if (prop in ["WindowParts","Shape"]) and obj.ViewObject:
self.colorize(obj)
if obj.Shape:
if not obj.Shape.isNull():
self.colorize(obj)
def onChanged(self,vobj,prop):
if (prop == "DiffuseColor") and vobj.Object:
if len(vobj.DiffuseColor) < 2:
self.colorize(vobj.Object)
if vobj.Object.Shape:
if not vobj.Object.Shape.isNull():
self.colorize(vobj.Object)
def setEdit(self,vobj,mode):
taskd = _ArchWindowTaskPanel()
@ -217,20 +229,22 @@ class _ViewProviderWindow(ArchComponent.ViewProviderComponent):
def colorize(self,obj):
"setting different part colors"
print "Colorizing ", obj.Shape.Solids
solids = obj.Shape.copy().Solids
#print "Colorizing ", solids
colors = []
base = obj.ViewObject.ShapeColor
for i in range(len(obj.Shape.Solids)):
for i in range(len(solids)):
ccol = base
typeidx = (i*5)+1
if typeidx < len(obj.WindowParts):
typ = obj.WindowParts[typeidx]
if typ == WindowPartTypes[2]: # transparent parts
ccol = ArchCommands.getDefaultColor("WindowGlass")
for f in obj.Shape.Solids[i].Faces:
for f in solids[i].Faces:
colors.append(ccol)
print "colors: ",colors
obj.ViewObject.DiffuseColor = colors
#print "colors: ",colors
if colors:
obj.ViewObject.DiffuseColor = colors
class _ArchWindowTaskPanel:
'''The TaskPanel for Arch Windows'''

View File

@ -2,8 +2,8 @@
# Resource object code
#
# Created: Sun Jul 7 11:06:17 2013
# by: The Resource Compiler for PyQt (Qt v4.8.4)
# Created: Fri Aug 16 18:34:56 2013
# by: The Resource Compiler for PyQt (Qt v4.8.5)
#
# WARNING! All changes made in this file will be lost!
@ -27568,133 +27568,143 @@ qt_resource_data = "\
\x6c\x6c\x61\x64\x61\x20\x73\x75\x70\x70\x6f\x72\x74\x20\x77\x69\
\x6c\x6c\x20\x62\x65\x20\x64\x69\x73\x61\x62\x6c\x65\x64\x2e\x0a\
\x07\x00\x00\x00\x04\x61\x72\x63\x68\x01\
\x00\x00\x07\xcc\
\x00\x00\x08\x6e\
\x00\
\x00\x3d\x0e\x78\x9c\xed\x5b\x6d\x6f\xdb\x36\x10\xfe\xde\x5f\x41\
\xf8\xd3\x06\x74\xb5\x9d\xb7\x26\x81\xe2\x61\x6d\x9a\x36\x43\xbb\
\xa5\x73\xd6\x7e\x1c\x68\xe9\x6c\x71\xa1\x48\x8d\xa4\x62\xbb\xbf\
\x7e\x47\x4a\xb2\x2c\x5b\x52\xe2\xf8\x25\x40\xe0\xa2\x45\x25\x1e\
\x7d\x77\x3c\xdd\x3d\x77\x47\x4a\xde\xaf\x93\x88\x93\x7b\x50\x9a\
\x49\x71\xd1\xea\xbe\xe9\xb4\x08\x08\x5f\x06\x4c\x8c\x2e\x5a\x7f\
\xdf\x5e\xfd\x72\xda\xfa\xb5\xf7\xca\x4b\x58\x31\xe9\x08\x27\xf5\
\x5e\x11\xcf\xe7\x54\xeb\xde\xc7\x84\x9d\x9f\x5f\x32\xca\xe5\x08\
\xff\xe7\xa3\x3e\x18\x83\x3f\xd6\xbf\x29\x3f\xf4\xda\xe9\x1c\x9c\
\x3c\x66\xc1\x08\x0c\x71\xf7\x17\xad\xaf\xdf\xdd\x6d\x8b\x08\x1a\
\xc1\x45\xab\x89\x87\x15\x45\xbc\x58\xc9\x18\x94\x99\x66\x3f\x18\
\x81\x8c\xc0\xa8\xa9\x23\x12\x4f\x81\x6f\xdc\x15\xf1\x26\xbd\x8e\
\xd7\x9e\x64\x37\x53\x7b\x33\xcd\x6e\x50\x03\x13\xf6\x8e\xdf\x1e\
\x7b\xed\xf4\x32\x1d\x0e\x81\x8d\x42\xd3\x3b\x39\x38\xf3\xda\xd9\
\xb5\xe3\xd9\xce\x99\x7a\xed\x5c\x78\x95\x26\x63\x26\x02\x39\xbe\
\x65\x86\x43\xa6\x8c\x36\x0a\x75\xef\x7d\x04\x01\x8a\x72\xa2\xb3\
\xb5\x78\xed\x8c\xb0\xcc\x92\xd3\xa9\x4c\x0a\xdb\x7c\x7b\x27\x27\
\x9f\xdd\x50\xc6\x71\x41\xa4\x8e\xa9\x8f\x8c\x5a\xd9\x02\x44\x12\
\x0d\x40\xf5\x4e\xbc\x76\x76\x95\xaa\x3f\x2f\x61\x89\x45\x44\xd5\
\x88\x89\x05\x0e\x67\x8d\x1c\x98\x81\xa8\xb0\xe4\xfc\xb3\xfc\xa8\
\x64\x12\xa3\xce\xf9\xd3\x1c\xe5\xf7\xe9\xf4\x25\xe1\xa6\x30\x56\
\x85\xbd\xec\x33\x27\xfd\x0a\xa3\x2d\xeb\xd4\x68\xba\x4c\x18\x7a\
\xad\x61\x3e\xe5\xe9\xe8\x3f\x07\x85\xdc\x62\x41\x15\x8c\x3e\x2d\
\x31\x0a\xa5\x62\x3f\xa4\x30\x15\xac\x16\x99\x2d\x9b\xe8\x33\x1d\
\x00\xcf\x39\x71\x7b\x53\xfa\x79\x85\x8d\x60\x62\x4a\x13\x66\x76\
\xba\x84\x21\x4d\x38\xb2\x96\x5c\x2a\x32\xc4\x7f\x63\xca\xf9\xa2\
\xa5\xaa\xcd\x95\x0e\xa6\xba\xcd\x29\xdf\x2e\x6b\xbf\xb4\x18\xeb\
\x70\xa0\x96\xec\xd0\x77\xc3\x8d\xcb\xc0\xb9\x80\x53\x0d\xe2\xc6\
\xc2\x6a\x00\x5d\xad\xf7\xd5\x9c\x9f\x7f\x9a\xf1\xf3\xda\x6e\xf0\
\xa1\x05\x2c\xc7\x03\xfb\x01\x9f\x98\xc0\x27\xa5\x4d\x80\xe1\x76\
\xd1\xea\x2c\x9a\x0e\x67\x94\x46\x72\x34\x38\xea\x94\xc0\x60\x46\
\xcd\x80\xe0\xa0\x53\xc2\x84\x42\xad\x45\x86\x35\x96\x4e\x0d\xb7\
\x82\xa5\xcb\x6e\xe3\x60\xf1\x46\xc1\xf0\xbd\x7d\xd6\xef\x12\x63\
\xd0\x8c\x79\x90\x59\x5a\x8c\x34\xe7\x07\x83\x94\xd6\xe8\x51\x52\
\xf2\x5b\x16\x57\x3b\xd5\x6d\xc8\x34\xc1\xbf\x26\x04\x12\x2c\x39\
\x98\x80\x31\xf9\x8e\x4e\x46\xe4\xe0\x5f\x04\xc5\xc7\xfb\xda\x92\
\x12\x8e\xe7\x82\x0a\x6e\x6c\xc1\xfe\x0a\x82\xde\x41\xf7\xc8\x82\
\x70\xb0\x40\x1a\x29\x00\x91\x12\xd3\xcb\x32\x79\xc0\x13\x48\xa9\
\xee\xaa\xfc\xd8\x96\x44\x3d\x4e\x6b\x6b\xe6\x0f\xc2\xa6\x9b\x5a\
\x0f\xf3\x33\x8b\x58\x33\xb9\xa7\x85\xc2\x9e\x6a\x24\x2b\xee\x86\
\x9a\xf0\x61\x69\x5f\x64\xd0\xce\xf2\xec\xa6\xa2\xdf\x6b\xa7\x48\
\x38\x83\xc9\x12\x79\x5d\xd0\x5c\x0b\x32\x37\x06\x98\x48\x48\x7c\
\x93\x28\x78\x3e\xd4\x7c\x00\xfe\xf7\xb8\xb9\x4b\xdc\x7c\x28\x17\
\xaf\x87\x9c\xfd\xdc\xdb\x76\x0b\x9f\xdd\xe3\x4e\x3d\x7c\x76\x4f\
\xce\x1a\xe0\xb3\x7b\x7a\xf2\x4c\xf0\x39\xb3\xd5\x1e\x43\xeb\x0b\
\xcf\x93\xf5\x0a\xcf\xe3\xcd\x15\x9e\xae\xf7\x79\x46\x10\x3d\xda\
\x83\x68\xbd\xad\x77\x0d\xa2\x87\x8d\x0f\x63\x15\xe8\x3a\x3c\xac\
\x47\xae\xa3\xe3\x06\xe0\x3a\x79\x2e\xdc\xfa\xee\x22\x61\x0f\x5a\
\xf5\xa0\xd5\x3d\x5a\x0f\xb5\x4e\x36\x8c\x5a\x64\x64\x65\x3d\x1f\
\x74\x35\xa3\xf0\x1e\xba\x76\x0a\x5d\xcd\x79\x64\x15\xe8\x3a\x6b\
\x80\xae\xee\xe9\x61\x53\xcf\xda\x39\x7c\x56\xf0\xfa\x68\x6d\xb7\
\x47\xb0\x06\x04\xeb\x3c\x1e\xc1\x0a\x0f\x0c\xc1\xbf\x9b\xdf\x1b\
\x9d\xb9\x9f\x25\x0c\xe4\xe4\x9f\xd3\xa7\xf7\x1e\xd7\x43\x6c\x3b\
\xd2\xf6\xc3\xb1\x83\xe0\x35\x19\x87\x20\xc8\x01\xd1\x2c\x62\x9c\
\x66\x7b\x83\x84\x62\xf3\x31\x00\xfc\x09\xc2\xa0\x10\xd8\x83\xd8\
\x99\xd8\xb1\x30\x45\x12\x11\x80\xe2\x53\x4b\xd3\x77\x60\x90\x8f\
\x46\x84\xe4\x1c\xe7\x93\x7f\x25\x13\x10\x10\x84\x08\x49\xa4\x80\
\xd7\x84\x8a\xc0\x35\x3a\x66\x2c\x33\xce\xd9\x54\x5f\x46\x60\xa7\
\x3c\xbd\xb5\xa9\x47\xf0\xdf\x51\x8b\x4c\xda\x80\x6a\x98\x53\xd3\
\x2e\x35\x96\x5a\xb3\x01\x5f\x43\xf2\x0a\x91\x62\x0d\x62\x77\x78\
\xfa\x99\x0a\x2f\x32\x52\xca\xc4\x12\xaf\xb9\x79\x4f\x38\x0f\x28\
\xda\xec\xc7\x9d\x08\x5c\x5f\xbd\x27\x2c\x8a\xa5\x32\x9b\x3e\x06\
\xd8\xdc\x21\xc0\xd9\x56\x30\xe1\x81\x16\xad\x09\x13\x1c\xf3\x14\
\x16\x30\x6a\x03\xa6\x63\x5c\x14\x09\x60\x90\x8c\x48\x04\x5a\xd3\
\x91\x8b\x1c\xc6\x21\xb3\xad\x8d\x7c\x6b\xe9\x21\x0e\xad\xb1\x35\
\x51\x1f\xbf\xfd\x10\xab\xad\xb2\x02\x3b\x09\x56\x36\xf4\x2f\xad\
\xd4\x17\x19\xa4\xeb\x7b\xee\xf1\x36\x3c\x77\xb3\xb9\x6c\xe6\x96\
\x69\x9a\xa1\x7c\x4c\xa7\xda\x26\xa6\xd4\x73\x31\x35\x8d\x99\x09\
\x5d\x46\xc2\x1c\x05\x4a\x50\x4e\xe2\xa9\x09\x25\xa6\x05\xaa\x34\
\xa8\xd7\x04\xee\x31\x47\xb0\x21\xb9\x1e\xfa\x7f\xc6\x20\xfa\x21\
\x20\x23\x2b\x46\x68\x34\x05\x87\x60\x1b\x1e\x7f\x25\x95\x0f\x65\
\x4d\x76\xe2\xf1\x43\x2b\x17\x57\x7a\xe3\x24\xdf\x64\x82\xf7\xde\
\x5f\xe1\xfd\x87\x5b\xc1\xed\x35\xf6\x91\xdf\x2b\xa0\x06\x3d\xdd\
\x25\x4b\xed\x1a\x55\xa0\x7e\x98\x1e\x87\xa7\x1b\xc7\xc4\x4c\xe3\
\xad\x54\x58\x2e\x61\x63\x69\x88\x51\x25\xb0\xed\xc4\x10\x9b\x3a\
\x59\xbb\xc1\x69\xdf\xad\x1c\xdd\xd6\xa9\xf1\x32\x6b\xaa\xf5\x1d\
\x76\x85\xed\x93\x15\x1c\xb6\x79\xcf\xae\xde\x63\xae\x1d\x00\x93\
\x61\xa2\x04\x73\x47\x1b\x3f\xf9\x54\x90\x88\xde\x81\x43\xe3\x48\
\x06\xc0\x49\x08\xf4\x7e\xfa\xf3\x6e\x72\xbd\xd3\x07\x7d\xe8\x2a\
\xd7\x68\xef\x46\xd5\x4d\x6c\x77\x2b\x7e\xf4\xc0\xee\xdc\xaa\x89\
\x1f\x7f\x2d\xec\xeb\x3f\xb3\x4e\x74\x96\xf0\xa9\x26\x3a\x19\x18\
\x45\x7d\xbb\x37\xa6\x71\x2a\xfa\x9b\x1a\x33\xec\x0b\x6d\x8b\x48\
\x74\x48\xe3\xa2\x5e\x40\x64\x09\xa6\x24\xa4\xf7\x90\x75\xbb\x33\
\xc6\x39\x93\xed\x14\x00\x7d\xc0\xac\x8f\xa0\x36\x93\xb7\xab\x82\
\x37\x17\xfc\xe7\x4c\xee\x3e\x0a\xaa\xa2\x60\x85\x77\xb7\x56\x88\
\x82\xb7\x1b\x8e\x82\x34\xeb\xdb\x5f\x17\x91\x60\x05\xb2\xc9\x7c\
\xe9\x6b\xab\xe4\xeb\x4b\x92\xbe\xba\xb7\x0d\x6f\xbe\x71\x22\x67\
\x7a\xa0\xd8\x0d\x88\x5b\xcd\xaf\x53\x15\xfe\x70\x32\xf7\x4e\x5d\
\xe3\xd4\x2b\xd4\xb4\x55\x27\x2c\xcd\x9b\xe0\xf5\xee\xf1\x61\xe2\
\xf3\x24\x00\xc2\x99\x36\xe7\x64\x9b\x27\x2a\x35\x81\xf9\x99\x09\
\xf8\x10\x30\xb3\x14\x98\x1c\x09\x60\x09\x4f\x0e\xcb\xdf\x6c\x55\
\x1c\xd1\x5f\x74\x86\xab\x81\x5b\x25\x91\xae\xa1\x24\x58\x2b\x33\
\xc3\xc0\xed\xb4\x40\x66\x85\xa1\x92\x51\xf5\xae\x55\xbd\x29\x1e\
\x6f\xec\xf6\x13\x5c\x9e\x53\x1f\x42\xc9\x03\x50\xb7\xf5\xf5\x1c\
\xa6\x0e\x7b\xe6\xf2\x1a\x2f\xde\x25\x8c\xdb\xd7\xbf\x3f\x70\x88\
\x70\x85\x37\x4a\x4e\xa6\x76\xfc\x8a\xcb\xf1\x2d\xa8\x88\x09\x7b\
\xe4\xb4\xa3\x7c\x76\xc7\xe2\x17\x19\xee\xdb\xdb\x64\x9d\xa1\xc0\
\xe3\x36\x59\x0f\x2e\x89\x02\x7b\x06\x80\x37\x1b\x7f\xdb\xba\x40\
\xa4\xb5\xd1\xed\xed\x56\x32\xf6\x03\x98\xd7\x04\x0d\x73\xdb\x9a\
\x4c\x60\xbb\x1e\xb9\xd3\x5a\x12\x24\x96\x4a\x1a\xcc\xba\x82\xff\
\x3e\xb0\xa9\x9a\x4a\x00\xf5\x1c\xbb\xab\x56\x81\x6f\x7f\x7d\xd9\
\xef\xb0\xd6\xbb\xec\xe9\x7a\xf9\xf8\xa9\xbd\xf9\x7b\xd4\x92\x62\
\xe7\xa3\x89\xcd\x7f\xb6\xac\xf4\xef\x04\xba\x06\x51\xd6\x43\x9f\
\xef\x8d\x87\xe6\xf5\xec\xdf\x78\xd8\xc8\x1b\x0f\x97\x32\x19\x70\
\xe8\xc7\x4c\x54\xe1\x5e\xe0\xa8\x1a\xa9\x6b\xed\xd5\xf7\x63\xf0\
\xd9\xd0\x16\x3e\x16\x85\x22\x2a\xa6\xc4\x30\xdb\x1c\xd8\x76\xe4\
\x9e\xc1\xd8\xd5\x49\x25\xdf\x8b\x12\x2c\x9b\xb0\x7d\xa1\x71\xcc\
\x19\x92\xb1\x62\xf2\xd1\x4f\xed\xac\x35\xf0\xea\x9e\xf2\x04\x16\
\x74\x4c\xd7\xd8\x3b\x78\xd3\x29\xff\xf1\xda\x19\x65\x9b\xa8\x88\
\xb1\x67\xab\xd1\xdb\x7c\xdd\x2f\x12\x19\x57\xaf\x5d\x4a\xc0\x90\
\xd7\x08\xe5\xcf\x87\x1e\x83\x07\x05\x14\x7c\xcb\x78\x94\x80\x60\
\xb9\x5e\x59\x21\xfc\xcb\x91\x9f\x05\xfd\xc1\x52\xd0\xe7\xf1\x7e\
\xb4\x14\xef\xa5\x50\x5f\x54\xa5\x14\xe0\x85\x91\xe6\x2c\x39\x67\
\xc6\x2c\xd5\xe4\x6f\x93\x67\x9f\xfb\x5d\xb4\x4e\x5a\x24\xfd\x6e\
\xef\xa2\xd5\xed\xb6\x6c\x2b\xe0\xc5\x6c\x12\xd1\x78\x98\x08\xb7\
\x1d\xd6\xfb\xef\xc6\xdd\x5f\x61\x0f\xf2\x05\x03\xb2\x2f\x13\xe5\
\x03\xea\x52\x9e\x65\x3f\xdd\xc4\x70\x94\x51\x2a\x51\x3b\x4d\xe6\
\x47\x52\x2d\xe7\x3e\xef\x9c\x7b\x8f\xaa\xf8\xa4\xd3\x3e\x8f\x89\
\xc1\x12\x44\xf7\xbe\xde\x24\x3a\xcc\xe9\xf9\xe0\xab\xd4\x5c\x14\
\x4b\x14\xcb\xa5\x9d\x7e\xf2\xa9\xdf\x84\xd6\x72\x6e\xd4\x59\x60\
\x51\x70\xb3\x26\x0b\x6f\x75\x55\x6a\xb3\xac\x72\x9d\x4a\x96\xdb\
\xe6\xd4\xca\xaa\xcd\x6a\x0b\x15\xd4\x9d\x28\x93\xf7\xc4\xd5\xca\
\x14\xd4\x9d\x28\x53\x4a\x4a\xd5\x1a\x2d\x4c\x59\x5f\xad\xf2\x80\
\xfb\x04\x59\x81\x76\x01\xa1\x5d\xe8\x64\x6f\x42\xd9\x5d\x64\xbc\
\xf7\xda\x09\xeb\xbd\xfa\x1f\x60\x53\xb8\xc3\
\x00\x4d\x6d\x78\x9c\xed\x5c\xeb\x73\xd3\x38\x10\xff\xce\x5f\xa1\
\xc9\x67\x20\x8f\x3e\x68\x3a\x6e\x18\xa0\x14\xb8\x81\xbb\x72\xed\
\x71\x1f\x6f\x14\x7b\x13\xeb\x90\x2d\x9f\x24\x37\x09\x7f\xfd\xad\
\x64\xe7\x61\xc7\x71\x1a\xe7\x45\x4a\x32\x30\xb5\x25\x79\x77\xb5\
\xfe\xed\x4b\x96\xed\xbc\x1e\x06\x9c\x3c\x80\x54\x4c\x84\x57\xb5\
\xe6\xcb\x46\x8d\x40\xe8\x0a\x8f\x85\xfd\xab\xda\x5f\xf7\x37\x2f\
\x2e\x6a\xaf\x3b\xcf\x9c\x98\x4d\x07\x9d\xe2\xa0\xce\x33\xe2\xb8\
\x9c\x2a\xd5\xf9\x10\xb3\xcb\xcb\x6b\x46\xb9\xe8\xe3\x5f\xde\xbf\
\x03\xad\xf1\x62\xf5\x46\xba\xbe\x53\x4f\xc6\xe0\xe0\x01\xf3\xfa\
\xa0\x89\x3d\xbf\xaa\x7d\xfd\xdb\x9e\xd6\x48\x48\x03\xb8\xaa\x95\
\xd1\x30\xac\x88\x13\x49\x11\x81\xd4\xa3\xf4\x82\x3e\x88\x00\xb4\
\x1c\xd9\x4e\xe2\x48\x70\xb5\x3d\x22\xce\xb0\xd3\x70\xea\xc3\xf4\
\x64\x64\x4e\x46\xe9\x09\x4a\xa0\xfd\xce\xd9\xab\x33\xa7\x9e\x1c\
\x26\xcd\x3e\xb0\xbe\xaf\x3b\xe7\xad\xb6\x53\x4f\x8f\x2d\xcd\xfa\
\x98\xa8\x53\x1f\x33\x2f\x92\x64\xc0\x42\x4f\x0c\xee\x99\xe6\x90\
\x0a\xa3\xb4\x44\xd9\x3b\x1f\x20\x04\x49\x39\x51\xe9\x5c\x9c\x7a\
\xda\x31\x4f\x92\xd3\x91\x88\xa7\xba\xf9\xf6\x56\x0c\x3f\xdb\xa6\
\x94\x62\x8e\xa5\x8a\xa8\x8b\x84\x6a\xe9\x04\xc2\x38\xe8\x82\xec\
\x9c\x3b\xf5\xf4\x28\x11\x7f\x96\xc3\x1c\x89\x80\xca\x3e\x0b\x73\
\x14\xda\xa5\x14\x98\x86\x60\xaa\xc9\xd9\x7b\xf9\x41\x8a\x38\x42\
\x99\xc7\x77\xb3\x3f\x3e\x4f\x86\xcf\x31\xd7\x53\x65\xcd\xe8\xeb\
\x1a\x7a\x34\xe6\xba\x50\x5f\xf3\xe2\x94\x6a\x2d\xe5\x83\x80\xd5\
\xcc\xa5\x3c\x69\xfd\xa7\x35\x65\x39\x9d\x4b\x01\xa1\x8f\x73\x84\
\x7c\x21\xd9\x0f\x11\xea\x02\x52\x79\x62\xf3\xda\xf9\x4c\xbb\xc0\
\xc7\x94\xb8\x39\xc9\x5c\x5e\xa0\x1e\x18\xea\xcc\x80\x89\x8a\xfe\
\xa6\x9c\xe7\xd4\x52\xac\x9b\xa4\x31\x11\x64\x46\xd2\x7a\x56\xd4\
\x39\xc9\x0d\xb0\x40\xce\x4d\xfa\xce\x36\x97\xca\x8c\x63\x01\x87\
\x6a\xf4\x0f\x39\xd1\x01\x21\xd5\xf9\xaa\x2f\x2f\x3f\x4e\xe8\x39\
\x75\xdb\xb8\x6c\x02\xf3\xb8\x67\x3f\xe0\x23\x0b\xf1\xb6\x28\xed\
\x21\x4c\xae\x6a\x8d\xbc\x9e\x70\x44\xa6\x65\x6c\xf5\xa7\x8d\x8c\
\xd1\x4f\x7a\x53\x83\x6f\x35\x32\xb6\x3f\x15\x2b\x4f\x70\x81\xa6\
\x13\xc5\xad\xa0\xe9\xe5\x18\x69\x36\xaa\x82\xc4\x4c\xf3\x72\x9b\
\x30\xc9\x0a\x6f\x7d\xf7\xad\x84\xde\xb5\x88\xbb\x1c\xee\x22\x16\
\xce\xfa\x02\xd3\x1b\x61\xaf\x67\x7b\x15\xf6\x76\xc5\x70\x89\x05\
\x04\x74\xc8\x82\x38\xc8\xcd\x2f\xa1\xd0\x69\xe3\xef\x65\xfb\xa2\
\x3d\xf9\xbd\xba\x68\x39\xf5\xb4\x73\x65\x4c\x3d\x50\x1e\x43\x31\
\xa3\x56\xa3\xf1\xb2\x91\xfd\x55\xe7\x63\x54\xf0\x3e\x34\x11\x6b\
\x21\x78\xdd\x19\x2b\xb7\x37\x11\xa3\xe7\x23\x6f\x62\x21\xbb\x5b\
\xaa\xfd\xe5\xdc\xbe\x08\xaf\x9e\x86\xea\x5d\x21\xa6\x08\xee\x17\
\x15\xd1\xfe\xd1\x5a\xed\xcf\x0e\xf7\x93\x03\x80\xfb\x49\x63\x8f\
\x78\x4f\x6e\xe3\xaf\x04\xf8\x76\x45\xc0\xbf\x13\x5c\xc8\x7d\xe0\
\xdd\x32\x7e\x1b\x6b\x8d\x21\x3e\x8f\x76\xd7\xf4\x75\x93\xbe\xd2\
\x69\x09\xc1\xef\x59\x54\x3c\xb3\x7b\x9f\x29\x82\xff\xb4\x0f\xc4\
\x4b\x93\x41\x4b\x98\xf4\xf0\x7f\x08\x03\x62\x90\x42\x44\xf7\x5f\
\x4c\xcc\xf3\xe9\xe1\x0a\x50\xb1\x34\xf3\xe0\x30\x6d\xb9\xdc\x40\
\x82\xd7\x69\x35\x4f\x4d\x21\xe0\xe5\xba\xfa\x12\x20\x4c\x3a\x93\
\xc3\x6c\x77\x17\x8d\x2c\xe9\xb5\x47\xd9\x94\x62\x8e\xd5\x56\x0c\
\xca\xde\xad\x43\xb5\x27\xa7\x9e\xa4\xe4\x93\x7c\x3d\xd3\xbd\x6e\
\xf6\xbe\x56\xee\x5e\xd1\x6a\xef\xb4\x8c\x5d\x1d\x4b\xd8\x5b\xfa\
\xbe\x24\xe5\x3a\x26\xf0\x1b\x4f\xe0\xab\x56\x79\x9f\x21\xec\xff\
\xfc\x19\xfc\xe9\x01\xa4\x34\xcd\x3d\x65\x34\x13\x6b\x4f\x6e\xe5\
\xa1\xba\xe1\x4a\xa8\x2f\x4f\x75\x0f\xbc\x6c\x3d\x3b\x82\x7e\x39\
\xe8\x7f\xb9\xda\xb5\x59\xee\x0b\x0f\xbd\x78\x3d\x3f\x0c\xd0\xef\
\x19\xf5\xbf\x5e\x05\xdb\x6c\x3e\xd1\x12\x76\xd9\xfa\xfc\x7a\x45\
\xec\x04\x31\xbb\xad\x64\x9b\x67\x8d\xc5\x95\x6c\xf3\xbc\x5d\x52\
\xc9\x36\x2f\xce\xf7\x54\xc9\x4e\x74\x75\x2c\x67\x17\x3f\x8c\x9a\
\xf5\xcf\x15\xcc\xb8\x3c\xa7\x29\x4b\xd8\xcc\x83\xcf\xfd\xd5\xb3\
\xe5\x41\xf7\x58\xcf\x6e\xba\x9e\x2d\x4f\x03\x16\xe3\xe4\x46\xe2\
\x80\xc4\x07\xfe\xcc\x3e\xbf\xbc\x6e\x59\xc5\xd3\x9e\x9c\x2c\x76\
\xb4\xa7\x67\x25\x7e\xf6\x7c\x5f\x6e\x36\x31\xe5\x83\xf6\xb1\x95\
\x12\x98\xaa\xae\xef\x83\xa1\xf9\xf3\x43\xba\xdc\x43\xae\x02\xe9\
\x76\x09\xa4\x9b\x17\x27\x65\xab\xe0\x8d\x93\xbd\x82\xda\xde\xaa\
\x83\x46\xf6\x96\xb3\x87\xcc\x3e\x83\x47\x23\xd0\x07\xf7\x7b\x51\
\xe5\xe8\x9a\x0e\x53\x34\x2e\x79\x9e\x5b\x96\x42\x7f\xea\x61\xf6\
\x9c\x64\xd1\x96\x1c\x78\xcf\xc9\xc0\x87\x90\xb4\x88\x62\x01\xe3\
\x54\x92\x01\xe5\x5c\x11\x8a\x39\x74\x17\xf0\x12\x34\xc5\x30\xc4\
\x54\xda\x8c\xc4\xc4\x9b\x49\x12\x87\x1e\x48\x3e\x32\x7d\xea\x3b\
\x68\xa4\xa3\xc8\x80\x71\x8e\xe3\xc9\xbf\x82\x85\xe0\x11\x8c\xdb\
\x82\x88\x10\x9e\x13\x1a\x7a\x36\x5f\xd7\x03\x91\x52\x4e\x87\xba\
\x02\x23\x17\x0e\xa9\x9e\xa1\x2f\xf6\x21\xbf\xa1\x14\x29\xb7\x2e\
\x55\x30\x23\xa6\x99\x6a\x24\x94\x62\x58\xbb\x56\xe7\xbc\x82\xa5\
\x18\x85\x98\x67\x46\x77\xa9\x08\x4f\xd2\x52\xb2\x9d\x19\x5a\x33\
\xe3\x2a\xec\x72\x9b\x56\x8b\x8f\xdb\xe7\xf6\xe9\xe6\x1d\x61\x41\
\x24\xa4\xde\xf4\x0e\xb7\xcd\xed\x6f\x6b\x6f\xc5\x27\x2c\x09\xb7\
\x65\x3e\xc1\x12\x4f\xdc\x02\x5a\xad\xc7\x54\x84\x93\xc2\x02\xbb\
\x1b\xf7\x49\x00\x4a\xd1\xbe\xb5\x1c\xc6\x21\xd5\xad\xb1\x7c\xa3\
\xe9\x1e\x36\xad\x51\x61\x97\x3c\xd1\xf3\xc5\x20\x27\xc0\x4e\x8c\
\x95\xf5\xdc\x6b\xc3\xf5\x49\x1a\xe9\xfa\xc8\x3d\xdb\x06\x72\x37\
\x1b\xcb\x26\xb0\x4c\xc2\x0c\xe5\x03\x3a\x52\x26\x30\x25\xc8\xc5\
\xd0\x34\x60\xda\xb7\x11\x09\x63\x14\xc8\x90\x72\x12\x8d\xb4\x2f\
\x30\x2c\x50\xa9\x40\x3e\x27\xf0\x80\x31\x82\xf5\xc8\xa7\x9e\xfb\
\x47\x04\xe1\x9d\x0f\x48\xc8\xb0\x09\x15\xaa\x82\x83\xb7\x0d\xc4\
\xdf\x08\xe9\x42\x56\x92\x9d\x20\xbe\x67\xf8\xe2\x4c\x6f\x2d\xe7\
\xdb\x94\xf1\x11\xfd\x05\xe8\x3f\xd9\x8a\xdf\x5e\x63\x39\xf4\x9d\
\x04\xaa\x11\xe9\x36\x58\x2a\xbb\x06\x0a\xd4\xf5\x89\x51\x6b\xba\
\xfe\x49\xf4\x28\xda\x4a\x86\x65\x03\x36\xa6\x86\x68\x55\x21\x84\
\x1a\x4d\x6c\x64\x79\xed\xc6\x4f\xbb\x76\xe6\x08\x5b\x2b\xc6\xd3\
\xcc\xa9\x36\x50\x7d\x34\xb7\x82\xd8\x25\x6b\x55\xab\x7a\x6c\xbc\
\x3a\x34\xaf\x24\x4c\x4a\x88\x89\xa7\xa6\x8a\xa8\xb8\xab\x25\x75\
\xcd\x4a\xa3\xc2\xa1\xe8\xb6\xe5\x80\x61\x42\x6f\x72\x7b\xa2\x7c\
\x1a\x4d\x1d\x3d\x42\xc2\x1b\x11\x9f\x3e\x40\x5a\xa6\x4c\x08\x8f\
\x89\x6c\xc7\x73\xdf\x01\xba\x6b\x44\xe3\x84\xdf\xae\x32\x95\x31\
\xe3\x3f\x26\x7c\x8f\x56\x50\x64\x05\x2b\xbc\x4f\xb2\x82\x15\xbc\
\xda\xb0\x15\x24\xee\xda\x5c\x3d\xb5\x04\xc3\x90\x0d\x67\x73\x16\
\x93\xde\x7c\xba\x26\xc9\x9b\x44\xdb\x40\xf3\xad\x65\x39\x91\x03\
\xd9\x6e\x80\xdd\x6a\xb8\x4e\x44\xf8\xdd\xf2\x3c\x82\x7a\x01\xa8\
\x57\x48\x46\x8a\x56\x67\xab\x6e\xaa\x78\x3f\x74\x79\xec\x01\xe1\
\x4c\xe9\x4b\xb2\x87\xe5\xd9\xcf\x2c\x84\xf7\x1e\xd3\x73\x86\xc9\
\xb1\x03\x4c\x47\x65\xb3\x7c\x63\xd2\x99\x80\xbe\x50\xa9\x5f\xf5\
\xec\x2c\x89\xb0\x95\x00\xc1\x24\x87\x69\x06\xb6\x44\x86\x54\x0b\
\x3d\x29\x82\xe2\xe5\x86\xc5\xaa\x78\xbc\xb2\xeb\x15\x20\xcf\xa9\
\x0b\xbe\xe0\x1e\xc8\xfb\x85\xf7\x10\x67\x63\x9f\xf2\x3d\xc7\x83\
\xb7\x31\xe3\xe6\x6d\xd4\xf7\x1c\x02\x9c\xe1\xad\x14\xc3\x91\x69\
\xbf\xe1\x62\x70\x0f\x32\x60\x58\x1f\xd9\xf3\x58\x86\x4c\xf9\xd3\
\x91\x3b\x0b\x72\xdf\x59\x74\xf4\x01\xc5\x3e\x60\xcd\x67\xd3\x4b\
\x22\xd8\x62\xfc\x58\xc0\x9b\xec\x0c\x63\x84\x0f\x6a\x1f\x4f\x69\
\x96\xba\x81\x75\xea\xaa\x12\x47\x80\xe1\xd7\x56\x39\x18\x8c\xa9\
\x26\x41\x8c\xcd\xb9\x8c\x35\xd1\xc9\x1a\xe6\xf1\x48\x13\xde\x9b\
\x45\xbe\x51\x5f\x70\x8a\x4f\xd2\x26\xb7\xb7\x8c\x3d\x09\xd7\x8f\
\x5b\xc6\x6e\x5d\x13\x09\xe6\x29\x0b\x9e\x6c\xfc\x55\xed\x69\xea\
\xb0\xb6\x0b\x7a\xb5\x95\xd4\x7a\x49\x72\x52\x66\xba\x33\x0b\xc7\
\x2c\xec\x09\x19\xd8\x4d\x2a\xc4\x8b\x4d\x2f\x29\x51\xeb\x0a\xf8\
\x5d\xb2\x6c\x9d\x70\x00\xb9\x8f\xf5\x6b\x23\xc0\xb7\x3f\xbf\x1c\
\xd7\xb0\x17\x43\xf6\x62\xbd\xa0\x59\x75\x07\xfe\x3b\x94\x92\x4a\
\xc0\x00\x61\x22\x94\xa9\xff\xdc\xef\x21\x42\x83\x48\x83\xd0\xfd\
\x6d\xf4\x2a\x9f\xcf\x71\xa3\xd7\x3a\x1b\xbd\xaa\x6c\x08\x5f\xc3\
\xf5\x45\xe0\xb2\x9e\xa9\x50\x8c\x17\x0a\x68\x38\x22\x9a\x05\x90\
\xec\x96\x7d\x60\x30\xb0\x79\x4c\x06\x7b\xe3\xfc\x85\x46\x11\x67\
\xd8\x8d\xa5\x8d\x8b\x38\x35\xa3\xd6\xf0\x57\x65\x6f\xfd\xef\x65\
\x1b\x39\xda\x9e\xc9\x17\xef\xc7\xf3\xfe\x25\x3c\x63\xc6\xec\xc7\
\x19\xc0\xdc\xc7\x46\x1e\x69\xf0\x53\x73\xff\x96\x52\xca\x1b\x7b\
\xd1\x8c\x56\x34\xf4\x39\x33\x4f\x8d\xbc\x55\x64\xe4\x63\x13\x3f\
\x2d\x32\xf1\xbc\x81\x17\x08\x97\x37\xee\xd5\xf3\xc0\x99\x41\x33\
\x23\xd2\x88\x34\xde\x9d\x9e\x7e\x4d\xe8\xaa\x76\x5e\x23\xc9\x67\
\x81\xae\x6a\xcd\x66\xcd\x94\xf6\x4e\xc4\x86\x01\x8d\x7a\x71\x68\
\x97\xb7\x3b\xff\xdd\xda\xf3\x1b\x29\x82\x2f\x68\xb7\x77\x22\x96\
\x2e\xa0\xe4\xd9\x51\xe6\xcb\x50\x68\xb5\x22\x48\x38\x2a\x2b\xc9\
\x6c\x4b\x22\xe5\xcc\xd7\xa3\x66\x36\xb4\x4d\xbf\x18\x65\x6e\xe9\
\x50\x63\xa6\xa2\x3a\x5f\x6f\x63\xe5\x8f\xfb\xc7\x8d\xcf\x12\x15\
\x53\xcc\x64\x0c\x95\x7a\xf2\x45\x29\xf5\xd2\x37\xda\xb6\xad\x56\
\x03\x79\xc6\xe5\x92\xe4\xb6\xd7\x15\x4a\x33\x2f\xf2\x22\x91\x0c\
\xb5\xcd\x89\x95\x26\xa5\xc5\x1a\x9a\xf6\xee\x44\x98\x71\x71\x5b\
\x2c\xcc\xb4\x77\x27\xc2\x64\x62\x57\xb1\x44\xb9\x21\xeb\x8b\x95\
\x6d\xb0\x5f\x38\x93\xa0\xac\x41\x28\x6b\x3a\xe9\x96\x34\xf3\x54\
\x08\xcf\x9d\x7a\xcc\x3a\xcf\xfe\x07\xb7\xee\x27\xe9\
\x00\x00\x07\x4c\
\x00\
\x00\x29\xd1\x78\x9c\xed\x59\x5b\x8f\xe2\x46\x16\x7e\xef\x5f\xe1\
@ -31365,6 +31375,116 @@ qt_resource_data = "\
\x55\x4c\x69\x8a\x07\xe9\x7b\x88\xe6\x87\xfa\x1b\xc0\x5e\xa3\xb6\
\x8e\x99\x2c\x6e\xae\xae\x6d\x7d\x71\x73\xf5\x1f\x81\x50\x39\x69\
\
\x00\x00\x06\xbf\
\x00\
\x00\x19\x91\x78\x9c\xed\x57\xdd\x6f\xe3\x44\x10\x7f\xef\x5f\x61\
\x7c\x2f\x20\x62\x7b\xbf\x6c\xef\xba\x49\x11\xe2\x04\x42\x02\x21\
\xc1\x9d\x78\x3c\x6d\xec\x4d\x62\xea\xd8\xd1\xda\x69\x92\xfe\xf5\
\xcc\xfa\xdb\x8d\xdb\xde\x01\xc7\x0b\x38\x6a\x13\xcf\xc7\xce\xce\
\xcc\x6f\x66\x67\x97\xdf\x9c\xf7\x99\xf5\xa0\x74\x99\x16\xf9\xca\
\xc6\x2e\xb2\x2d\x95\xc7\x45\x92\xe6\xdb\x95\xfd\xfe\xdd\xf7\x0e\
\xb7\xad\xb2\x92\x79\x22\xb3\x22\x57\x2b\x3b\x2f\xec\x6f\xee\x6e\
\x96\x5f\x38\x8e\xf5\x9d\x56\xb2\x52\x89\x75\x4a\xab\x9d\xf5\x63\
\x7e\x5f\xc6\xf2\xa0\xac\x2f\x77\x55\x75\x88\x3c\xef\x74\x3a\xb9\
\x69\x4b\x74\x0b\xbd\xf5\xbe\xb2\x1c\xe7\xee\xe6\x66\x59\x3e\x6c\
\x6f\x2c\xcb\x02\xbb\x79\x19\x25\xf1\xca\x6e\x15\x0e\x47\x9d\xd5\
\x82\x49\xec\xa9\x4c\xed\x55\x5e\x95\x1e\x76\xb1\x67\x0f\xe2\xf1\
\x20\x1e\x1b\xeb\xe9\x83\x8a\x8b\xfd\xbe\xc8\xcb\x5a\x33\x2f\xdf\
\x8c\x84\x75\xb2\xe9\xa5\xcd\x6e\x4e\xb4\x16\xc2\x42\x08\x0f\x11\
\x8f\x10\x07\x24\x9c\xf2\x92\x57\xf2\xec\x4c\x55\x61\x8f\x73\xaa\
\x04\x21\xe4\x01\x6f\x90\xfc\x38\xa9\xe8\x9c\x41\x28\x9e\xdd\x4c\
\xcd\x1d\x5b\x87\xf0\x1f\xe0\xaf\x57\xe8\x08\x6e\x59\x1c\x75\xac\
\x36\xa0\xa9\xdc\x5c\x55\xde\xdb\x77\x6f\x7b\xa6\x83\xdc\xa4\x4a\
\x46\xcb\x74\xd1\x9f\xd8\x9d\xa4\x24\x97\x7b\x55\x1e\x64\xac\x4a\
\xaf\xa3\xd7\xfa\xa7\x34\xa9\x76\x2b\x3b\x60\x87\x73\xfd\xbe\x53\
\xe9\x76\x57\x8d\x08\x69\xb2\xb2\xc1\x43\xc2\x03\x54\xbf\x77\x7b\
\x88\x7a\x24\x21\x97\x92\x46\xb4\x5d\x78\xcc\x62\xdc\x65\x96\x16\
\x82\x8a\xa9\x76\x52\xc4\x66\x4b\x2b\xfb\x5b\x1d\xef\x3e\xfc\x66\
\x76\xe6\x76\x81\xec\xd7\x29\x8e\xd5\xe1\x58\x7d\x50\xe7\x4a\xe5\
\xcd\x82\xe0\xca\xc8\xaf\x9a\x6d\xd4\xdc\x89\x4f\x23\x8c\x63\xfb\
\x0e\x28\xcb\x44\x6d\x4a\xc3\x69\xdc\x31\x6f\xe0\x0f\xa9\x79\xc0\
\x85\x9c\x28\xa9\x7f\xd0\x32\x49\x01\x89\x8d\x5c\x23\x39\xe5\x50\
\x1a\x86\xad\x0e\x68\x95\x55\x71\xe8\x64\xdb\x30\x01\x05\x64\x1a\
\x4f\x9b\xa7\xd8\x6c\x4a\x05\xe1\x44\x23\x5a\x59\x5d\x32\xd5\x48\
\x3b\x71\x91\x15\x3a\x7a\xb3\x91\x9b\x0d\x59\xdf\xd6\xa4\x02\x62\
\x91\x56\x97\x08\xdf\xda\x96\xf7\xaa\x35\x8e\x67\xac\xe1\x57\xac\
\x6d\xa4\x44\xe8\x59\x6b\x4b\x6f\xea\x76\x4b\xed\xb3\x72\x80\xf0\
\x1e\x54\x6c\x2a\xb2\x33\xd3\xa7\xb5\xba\x18\x10\x4e\x45\x69\xd2\
\x6f\x67\x40\xc8\xe1\xc3\x19\xa2\x62\x45\x16\x25\xf0\x0f\xcf\x4a\
\x5c\x1a\x09\x0c\x45\x06\x5f\x68\x56\xe6\xd1\x40\xf5\x85\x65\xda\
\x1d\x38\x85\x4e\xb7\x29\x40\xa2\x96\x23\xd8\xa5\xf5\x33\xd5\x81\
\xa0\x8e\x7c\x03\x84\xf0\x21\x26\x26\x16\x32\xbb\xc2\x48\x67\x06\
\x22\x9b\x81\xda\xca\x96\xd9\x49\x5e\xca\x7e\xcd\xba\xde\xa3\x9d\
\x56\xd0\x9f\xde\x5c\xa3\xc9\x99\x5a\x9f\x1a\xa1\x48\xf8\x4e\xd0\
\x0b\x6c\x5b\xf2\xfb\x3c\xad\xa0\x19\x1d\x4b\xa5\xeb\xb2\xf9\x25\
\x7f\x5f\xaa\x2b\xa9\x77\x5a\xe6\x25\x74\x8f\xfd\xca\xde\xcb\x4a\
\xa7\xe7\x2f\xa1\xe1\x53\x9f\x84\xdc\x5f\x20\x97\x50\x81\x21\xac\
\x7c\x01\x9d\x84\x09\x4c\xa0\x37\xd1\x05\x71\x31\x09\x38\x23\x6c\
\xe1\x70\xea\x22\x82\xfc\x20\x58\x38\x04\x23\x17\x0b\x5f\xf8\x5f\
\xf5\x36\x62\x48\x1d\xa6\xbe\x4b\x39\x84\x70\xa0\x42\xba\x44\xe8\
\xd2\x40\xf8\x10\xb8\x8e\xba\x99\x95\xdd\xcc\xca\x6a\x10\x15\x2e\
\x0b\x42\x46\x83\x21\xf2\x9f\x52\x9d\x0e\xfe\x98\xfa\x74\xe6\x6a\
\xe6\x33\x56\xa8\x83\xfe\xad\x1a\xfd\x0c\x28\xc5\x8c\xbd\x80\x51\
\x86\x11\xff\xe7\x10\xba\x40\xe6\xe3\x06\x82\xfb\x44\x30\xf8\x4d\
\x10\x71\x39\x14\x22\x9d\x82\x8f\x10\xdf\x25\x01\x43\x64\x02\xbe\
\x20\x24\x6e\x28\x42\x1a\x4c\xc0\x77\x2d\xbb\x99\x95\x05\xf0\x51\
\xe6\x52\xe6\x63\xce\x5f\x05\xdf\x6b\x01\x9d\x41\xa7\x89\xe3\x33\
\x58\x99\x4d\xbf\x79\xae\xd2\xff\x32\x6c\x7b\xcc\x61\x16\x3c\x8f\
\xcc\x8f\xb4\x86\xe6\xac\xe1\x79\x6b\xfc\xaf\xe1\x72\x12\xf2\x97\
\xb3\x33\x9f\xc9\xf9\xac\xcf\x23\xe4\x6f\xc2\xee\xe3\xb0\x3d\x57\
\x20\x94\x7d\x7a\x9d\x3d\x87\xaf\x26\xcc\x4b\xcf\x4c\x30\xf5\xaf\
\xfe\xe0\x35\xc3\x54\xf2\x90\xaa\xd3\x30\xe6\xac\x65\xbf\xb3\x83\
\xdc\xaa\x3a\xd7\x60\xb7\x49\x76\xcb\x58\x17\x3a\x51\xba\x63\x05\
\xf5\x33\x61\xb5\x70\x68\xee\x0b\x37\xd3\xdd\x99\x55\x7b\x3e\x9a\
\xe7\x97\x3b\x99\x14\x27\x48\xc8\x53\xe6\x63\x51\x40\x0a\xa8\xcb\
\xb9\x40\x3c\xa4\x4f\xd9\x75\x12\xa9\x1b\xc0\x98\x46\xaf\x74\x4d\
\xde\x71\x00\xc7\x52\x88\xc4\x35\xf3\xa8\x35\x04\xd4\xc9\xe4\x45\
\x81\x53\xf5\x57\x87\xdb\x72\x57\x9c\xb6\xda\x04\xa7\xd2\x47\xf5\
\x54\x13\x66\xd2\xa3\xb9\x8b\x38\xc7\x26\xc9\xed\x04\x3c\x92\x30\
\xba\xce\x7a\x5d\x9c\xe7\x17\x38\xa5\x39\x38\xeb\xb4\x33\x35\x16\
\xe4\x2a\x24\xad\x44\x37\x65\x63\xe4\x87\xcf\x88\x9c\x87\xda\x7e\
\xca\xba\xcc\xb0\x8a\xf5\x1f\x00\x14\xe7\x20\xab\x1d\xec\x7c\x23\
\xb3\xf2\x6a\x77\x65\x2e\x0f\x4e\x5e\x24\xaa\x9c\xdf\x7d\xbb\xc4\
\x0b\x12\xad\xfd\xbd\x3c\xa7\xfb\xf4\x51\x25\xa6\x21\xb4\x90\xdc\
\xab\x4a\x26\xb2\x92\x03\xfc\x3a\x0a\xd4\x91\xdf\x4d\xda\x70\x0b\
\x8b\x7e\x7d\xfb\x7d\xdf\x99\xe2\x38\xfa\xbd\xd0\xf7\x43\x53\x31\
\x02\x72\x0d\x83\xfd\xca\xee\xbb\xa5\x99\xdf\xe3\xc8\x94\xac\xac\
\xee\xd2\x3d\x80\xca\x5c\xb9\xbe\x86\x9b\x0f\x14\x42\xcf\x98\x08\
\x9b\x31\x74\x58\xb4\x59\x56\xab\xe6\x4a\x35\x7b\x0b\x4d\xe2\x7d\
\x6a\x94\xbc\xdf\xaa\x34\xcb\x7e\x34\x46\x46\x1d\xb4\x5d\x34\xad\
\x32\x75\x57\xdb\x6c\x7e\x76\x5e\x78\xad\x1b\x5d\x0b\x1c\x79\xb9\
\xf4\xba\x30\xd4\x6f\xdb\x21\x3c\x13\x5c\xf6\x11\xce\xe4\x5a\x65\
\x2b\xfb\x27\xc3\xb4\xae\xb8\x5b\x5d\x1c\x0f\x7b\xc8\x4f\xab\xde\
\x85\xd5\x64\xbd\x1f\xc5\x9b\xf6\xde\x76\x76\x54\x3f\xb7\x1b\x70\
\x6a\xd4\xe6\x75\x71\xaf\xa2\x37\xdc\x37\x9f\xf6\xb5\x01\x6d\xc4\
\xba\x57\xd3\x9d\xc0\x66\xb4\x3e\x56\xd5\x98\xf6\x47\x91\xe6\x11\
\x6c\x23\x4f\x3a\x2a\x04\x4e\xe9\x0c\x00\x51\x0d\xda\xc3\x91\xd5\
\x12\x12\x09\x8d\x40\x6b\x79\x89\xf8\x82\x8d\x89\xcd\xc9\x02\xa7\
\xcd\x5e\xea\x7b\xa5\xa3\xbc\xc8\xd5\xed\x43\x5a\xa6\xeb\x34\x33\
\x2b\xd4\x3f\x33\x75\x9b\xa4\xe5\x01\x7c\x86\x9b\xae\xd9\xc5\x6d\
\x01\x77\xbc\x4d\x56\x9c\x7a\xbe\xca\x25\x7c\x39\x6b\x19\xdf\x6f\
\xeb\xed\x45\x32\x86\x6a\x3e\x66\xb2\x52\xb5\xfb\xc3\xc1\xe6\x9a\
\xa1\x05\xe6\x5f\x8e\xda\x67\x38\x24\x20\x2f\x3f\x5b\x04\x06\x53\
\x1c\x08\x1a\x2c\x18\x34\x20\xc4\x18\x66\x16\x73\x91\x2f\x04\x47\
\x78\xe1\xfb\x30\x26\x23\x1c\xf2\x49\xd3\x37\x19\xa0\x02\xd1\xb9\
\x16\x9e\x43\x24\xab\x42\x3b\xd0\x98\x1e\x64\x75\xd4\xca\x94\x6f\
\x7f\x60\x8e\x73\xf7\x9a\xd2\xd5\x75\xcb\xd4\xaa\x81\x2d\xd4\x6b\
\x6c\x9e\xe9\x41\x04\x2b\xc0\xc4\x8f\x46\xe3\x67\xe7\x1f\x0b\x84\
\x08\xc3\x85\xef\x42\xbb\x0f\x11\x62\x96\x2f\x5c\x81\x42\xce\x17\
\xdc\xcc\xdf\x84\xf3\x9a\x04\xb7\x84\x00\xae\x03\xe6\x0e\xcf\x45\
\xe0\xf3\xd9\xd0\x3c\xda\x4f\xa0\xf7\x3f\xd8\x5e\x06\xdb\xe7\x49\
\xfd\x7c\xf2\xaf\xa1\x7d\x95\x7a\xe6\x12\x02\xd0\x16\xfe\x02\x03\
\xca\x79\x88\x42\x66\x51\x80\x03\x48\x61\xb1\xc0\xdc\x15\x3e\x25\
\x38\xb4\x18\x72\xfd\x80\xf9\x22\x58\x04\x30\x0b\x04\x70\x72\xd1\
\x59\x8c\x04\x30\x09\xc0\xca\x3e\x01\x2c\xe1\x00\x11\x16\xfa\xaf\
\x60\xe4\xb5\x88\xfd\xf7\x40\xf4\x6f\xb6\x87\x31\x42\xf6\xf3\x68\
\x08\x5c\x4a\x59\x80\x02\x7f\xc1\x60\xe8\x42\x08\x73\x0b\x2d\x18\
\xcc\xdd\x9c\x32\x8e\x2d\x07\x04\x7c\xc4\x02\xec\x8b\x85\xe3\xbb\
\x82\x21\x2a\x66\x72\xfe\xc2\x91\xf4\x2a\x02\x6a\x01\x7d\xcc\x94\
\x09\xf7\x23\x8c\xa5\xff\x63\xe2\xd3\x30\xd1\x1f\x52\xfe\xe8\xa6\
\x54\xf7\x04\xa8\x6b\x22\x10\x09\x4c\xa9\x53\x22\xe0\xde\x33\x73\
\x1a\xfc\xbd\xfa\x1d\xb2\xa7\x1e\x14\x80\x32\xf9\xcf\x66\x6f\xe9\
\x6d\xef\x6e\x96\x66\x7e\xbd\xbb\xf9\x13\xf5\x97\x97\x20\
\x00\x00\x0b\x26\
\x00\
\x00\x5f\x19\x78\x9c\xed\x5c\xdb\x72\xe3\x36\x12\x7d\xf7\x57\x70\
@ -31546,6 +31666,151 @@ qt_resource_data = "\
\xd6\x3c\x7b\x1b\x0c\x34\xd1\xc5\x5a\x70\x62\x48\x7c\x18\x6c\xc7\
\xb1\x5f\x18\x9d\x9e\xf6\x47\xe7\x27\xa7\xfe\x9b\xbd\xce\x4f\xfe\
\x06\xf2\x9a\xfe\xf0\
\x00\x00\x08\xea\
\x00\
\x00\x21\x8a\x78\x9c\xe5\x59\x6d\x8f\xa3\x38\x12\xfe\xde\xbf\x82\
\xcb\x7c\x99\xd6\x05\xe3\x17\x6c\x70\xa6\xd3\x2b\xdd\x8d\xf6\xb4\
\xd2\x9e\x76\x75\x3b\xa3\xfb\x38\x72\xc0\x49\xb3\x4d\x20\x02\xd2\
\x49\xe6\xd7\x5f\x99\x17\x07\x1a\x92\xee\x7d\x99\xd6\x49\xcb\x68\
\x26\xe0\x2a\x53\x76\xd5\x53\x8f\xab\x98\xbb\xef\x8e\xdb\xd4\x79\
\xd2\x45\x99\xe4\xd9\x72\x46\x10\x9e\x39\x3a\x8b\xf2\x38\xc9\x36\
\xcb\xd9\xe7\x4f\xdf\xbb\xe1\xcc\x29\x2b\x95\xc5\x2a\xcd\x33\xbd\
\x9c\x65\xf9\xec\xbb\xfb\x9b\xbb\xbf\xb9\xae\xf3\xcf\x42\xab\x4a\
\xc7\xce\x21\xa9\x1e\x9c\x1f\xb2\xc7\x32\x52\x3b\xed\xbc\x7f\xa8\
\xaa\xdd\xc2\xf3\x0e\x87\x03\x4a\xda\x41\x94\x17\x1b\xef\xd6\x71\
\xdd\xfb\x9b\x9b\xbb\xf2\x69\x73\xe3\x38\x0e\xd8\xcd\xca\x45\x1c\
\x2d\x67\xed\x84\xdd\xbe\x48\x6b\xc5\x38\xf2\x74\xaa\xb7\x3a\xab\
\x4a\x8f\x20\xe2\xcd\xce\xea\xd1\x59\x3d\x32\xd6\x93\x27\x1d\xe5\
\xdb\x6d\x9e\x95\xf5\xcc\xac\x7c\xd7\x53\x2e\xe2\xb5\xd5\x36\xab\
\x39\xb0\x5a\x89\x48\x29\x3d\x4c\x3d\x4a\x5d\xd0\x70\xcb\x53\x56\
\xa9\xa3\x3b\x9c\x0a\x6b\x9c\x9a\x4a\x31\xc6\x1e\xc8\xce\x9a\xaf\
\xd3\x5a\x1c\x53\x70\xc5\xc5\xc5\xd4\xd2\xbe\x75\x70\xff\x0e\xfe\
\xda\x09\xdd\x00\x2a\xf3\x7d\x11\xe9\x35\xcc\xd4\x28\xd3\x95\xf7\
\xf1\xd3\x47\x2b\x74\x31\x8a\xab\xb8\xf7\x9a\xce\xfb\x03\xbb\x83\
\x90\x64\x6a\xab\xcb\x9d\x8a\x74\xe9\x75\xe3\xf5\xfc\x43\x12\x57\
\x0f\xcb\x99\xf0\x77\xc7\xfa\xf9\x41\x27\x9b\x87\xaa\x37\x90\xc4\
\xcb\x19\xec\x90\x86\x02\xd7\xcf\xdd\x1a\x16\x16\x49\x18\x31\xda\
\xa8\xb6\x2f\xee\x8b\xfc\x10\xf9\x4e\x21\x25\x93\xc3\xd9\x71\x1e\
\x99\x25\x2d\x67\x3f\xab\xa2\xfa\xf2\x8f\xfc\x88\x3a\x37\xda\xb7\
\xe4\xfb\x6a\xb7\xaf\xbe\xe8\x63\xa5\xb3\xe6\x75\xb0\x91\xde\xae\
\x6a\xb1\x99\x86\x06\x3b\xea\x21\x9c\xcc\xee\x61\xe4\x2e\xd6\xeb\
\xd2\x48\x9a\xcd\x98\x27\xd8\x0d\xad\x65\x20\x85\x88\x68\x55\xfc\
\xab\x50\x71\x02\x38\x6c\xf4\x1a\xcd\xa1\x84\xb1\x20\x68\xe7\xc0\
\xac\xb2\xca\x77\x9d\x6e\xeb\x24\x18\x01\x9d\x66\x9f\xcd\x95\xaf\
\xd7\xa5\x06\x67\xe2\xde\x58\x59\x9d\x52\xdd\x68\xbb\x51\x9e\xe6\
\xc5\xe2\xdd\x5a\xad\xd7\x74\xf5\xa1\x1e\xca\x21\x46\x49\x75\x5a\
\x90\x0f\x33\xc7\x7b\xd1\x5a\x48\x26\xac\x91\x17\xac\xad\x95\xc2\
\xf8\xa2\xb5\x3b\x6f\xb8\xed\x76\xd4\x46\x65\x07\xee\xdd\xe9\xc8\
\xe4\x63\x67\xc6\x06\xb5\x3a\x19\x08\x0e\x55\x59\x6c\x97\x73\xc6\
\xc7\xee\xcb\x11\xbc\xe2\x2c\x1c\x46\xe1\x1f\x32\xa9\x71\x6a\x34\
\x08\xa4\x18\xfc\xe0\x49\x9d\xaf\x06\xa8\x57\x5e\xd3\xae\xc0\xcd\
\x8b\x64\x93\x00\x24\x6a\x3d\x4a\x10\xab\xaf\xe1\x1c\x70\x6a\x6f\
\x6f\x80\x90\xf0\xec\x13\xe3\x0b\x95\x8e\x30\xd2\x99\x01\xcf\xa6\
\x30\x6d\x39\x53\xe9\x41\x9d\x4a\xfb\xce\x3a\xdb\x17\x0f\x85\x06\
\x76\x7a\x37\x81\xa6\xbe\xed\xa1\x09\x86\x25\xb5\xe2\x4d\x3b\xf8\
\x39\x4b\x2a\xa0\xa1\x7d\xa9\x8b\x5f\x4c\x2a\xff\x94\x7d\x2e\xb5\
\xd5\x8a\xc0\xa5\x3e\x47\x61\xc8\x18\x3d\xbf\x3a\x02\x37\xd2\x10\
\x85\x42\x72\xd8\x50\x37\xba\x9e\xd4\x5d\x4f\xea\x16\x80\x28\x89\
\x7c\x11\xf8\x4c\x8c\x96\xf4\xa9\x50\x59\x09\x24\xb5\x5d\xce\xb6\
\xaa\x2a\x92\xe3\x7b\x38\x57\x04\xe5\x8c\xf2\x39\x86\x3f\xe7\x27\
\x97\x30\x1f\x71\x1f\x13\x31\x77\x03\x1f\x11\xc9\xb0\x4f\x6f\xbf\
\xb5\x8b\x5d\x72\xdd\xc9\xdc\x1d\xef\xe9\xba\x9b\xaf\xee\x9c\x71\
\x1a\x84\xb0\x73\x44\x99\x24\x80\xdc\x70\x0e\x54\xed\x4b\x42\x81\
\xfc\xd9\x9c\x22\x42\x45\xe8\x53\x7f\xee\x86\x0c\x61\x8a\xb9\x00\
\x67\x50\x82\xc1\x1b\x5c\xf2\xdb\x41\x28\x09\xe3\x88\x41\x7c\xd8\
\x20\x94\x32\x40\x6c\x1c\xca\xb1\xee\x7a\x52\x77\x10\x4a\xeb\xf9\
\xdf\x42\x80\x2e\x79\x0d\x05\xba\x53\xb4\xf4\x0d\x49\xd0\xc5\x6f\
\x45\x83\xdf\x00\xa5\xc4\xf7\xaf\x60\xd4\x27\x38\xfc\xf3\x10\x5a\
\xe7\x24\x46\x42\x86\x9c\x4a\x1f\xee\x29\xa6\x28\x04\xae\x63\x43\
\xf0\x51\xca\x11\x15\x3e\xa6\x03\xf0\x89\x80\xa2\x40\x06\x3d\x1a\
\x58\x4f\xea\xae\x27\x75\x01\x7c\xc0\x00\xcc\xe7\x24\x0c\x5f\x04\
\xdf\x4b\x0e\x9d\x40\xa7\xf1\xe3\x05\xac\x4c\x86\xdf\x5c\xa3\xf0\
\x5f\x87\xad\xc5\x1c\xf1\xc5\x65\x64\xbe\xd2\x1a\x9e\xb2\x46\xa6\
\xad\x85\xbf\x0f\x97\x03\x97\x5f\x8f\xce\x74\x24\xa7\xa3\x3e\x8d\
\x90\x3f\x08\xbb\xd7\x61\x7b\x2a\x41\x98\xff\xdb\xf3\xec\x12\xbe\
\x1a\x37\xdf\x79\xa6\x48\xac\xef\x6c\x6d\x63\xaa\xd5\xf8\x29\xd1\
\x87\x73\x25\xb9\x52\x76\x65\x3b\xb5\xd1\x75\xac\xc1\x6e\x13\xec\
\x56\xb0\xca\x8b\x58\x17\x9d\x48\xd4\xd7\x40\xd4\xc2\xa1\x69\xc8\
\x6e\x86\xab\x33\x6f\xb5\x72\x3c\x2d\x2f\x1f\x54\x9c\x1f\x20\x20\
\xcf\x85\x5f\xf3\x1c\x42\xc0\x11\x7f\x2e\x30\xe1\xe3\x12\x51\x0e\
\xb8\x92\x23\x21\x58\x62\x50\xd1\xcb\x80\xe3\xf1\xcc\x7d\x51\x80\
\x2b\xdd\x54\x9d\x34\x6c\xa7\xfe\xe9\x10\x5b\x3e\xe4\x87\x4d\x61\
\xdc\x52\x15\x7b\xfd\x7c\x26\x94\xfb\x7b\xd3\xe6\xb9\xfb\x26\xbc\
\x6d\x73\xd1\xd3\x30\x73\xdd\xd5\x2a\x3f\x4e\xbf\xe0\x90\x64\xb0\
\x4d\xb7\x6d\x57\x88\xa4\x23\x67\xb4\x1a\x5d\x03\x43\x30\x0f\x2e\
\xa8\x1c\xcf\x59\xfd\x5c\x74\x9a\x10\xe5\xab\x5f\x01\x22\xee\x4e\
\x55\x0f\xb0\xf2\xb5\x4a\xcb\xd1\xea\xca\x4c\xed\xdc\x2c\x8f\x75\
\x39\xbd\xfa\xf6\x15\x57\x34\x5a\xfb\x5b\x75\x4c\xb6\xc9\x57\x1d\
\x1b\x2a\x68\xc1\xb8\xd5\x95\x8a\x55\xa5\xce\xc0\xeb\x46\x20\x83\
\x78\xd7\xc6\x40\x83\xbb\xf8\xcf\xc7\xef\x2d\x27\x45\xd1\xe2\xbf\
\x79\xf1\x78\xa6\x13\xa3\xa0\x56\xd0\x35\x2d\x67\x96\x27\x4d\x73\
\x14\x2d\x4c\xb2\xaa\xea\x3e\xd9\x02\x9c\x4c\x37\xfb\x77\x68\x2a\
\x21\x05\xac\x60\xa0\x6c\x6a\xfc\xf3\x4b\x9b\xd7\x16\xba\xe9\x56\
\x27\x1b\xfc\x38\xda\x26\x66\x92\xf7\x4b\x95\xa4\xe9\x0f\xc6\x48\
\x8f\x3b\xdb\x97\x26\x55\xaa\xef\x6b\x9b\xcd\x6d\xb7\x0b\xaf\xdd\
\x46\x47\x7e\xbd\x5d\xde\x79\x9d\x1b\xea\xa7\xcd\xd9\x3d\x03\x5c\
\x5a\x0f\xa7\x6a\xa5\xd3\xe5\xec\x47\x23\x74\x46\xd2\x4d\x91\xef\
\x77\x5b\x88\x4f\x3b\xbd\x73\xab\x89\xba\xed\x73\x1a\x62\x5f\xc3\
\x36\x16\x59\x9e\x69\xe0\xf3\x22\x7f\xd4\x86\xde\x57\xac\xae\x25\
\xcc\x63\x83\xd1\x05\x85\x26\x23\xec\x86\x0c\x15\x81\x99\xc5\x6a\
\x5f\x55\xfd\xb1\x5f\xf3\x24\x5b\x80\xe5\x2c\xee\x46\xcf\x67\x51\
\x7b\x74\xe0\xfa\xea\xc4\xe0\x4a\x5d\xa4\x00\x91\x6a\xe1\x77\x63\
\xb1\x02\x0e\x28\x0a\x75\x5a\xf8\x48\x04\x62\x3e\xb0\x6c\x84\xcd\
\xe1\x02\x07\xce\x56\x15\x8f\xba\x68\xd6\xfe\x94\x94\xc9\x2a\x49\
\x8d\xad\xfa\x36\xd5\x1f\xe2\xa4\xdc\xc1\xe6\x17\x49\x66\xd6\xf6\
\x21\x87\x4e\x7a\x9d\xe6\x07\x2b\xd7\x99\x82\x1f\x77\xa5\xa2\xc7\
\x4d\xbd\xe8\x85\x8a\x20\xad\xf7\xa9\xaa\xce\x0c\x0d\xfe\xff\xb7\
\x43\x03\x14\x08\xc6\x49\x30\xf7\x29\x82\x53\x02\x8a\x61\x47\x00\
\xff\xfb\x42\x12\x36\xe7\x50\xfc\x06\x8c\x12\x3e\xa0\x75\xe3\x69\
\x26\x31\x9b\x22\xe9\x0c\xdc\x57\xe5\x85\x0b\x04\xf4\xa4\xaa\x7d\
\xa1\x4d\x9a\xda\x23\xb1\x1f\xa3\x97\x26\x8d\x7a\x56\x93\x93\x06\
\x9e\x90\x97\x91\xb9\x86\x47\x0d\xbc\x01\x6a\x7a\xdc\x2b\x30\xbb\
\xfd\x49\x4c\xa1\x95\x09\x11\x0d\x28\x17\x9c\x38\x3c\x40\x34\x0c\
\x89\xcf\xe7\x50\xcf\x87\x58\x0a\xe1\x70\x01\x87\x1c\xf6\x05\x99\
\xfb\x01\xf4\x41\x02\x9a\x83\x49\xcf\x7c\x9d\xbd\x25\xc2\xa6\x20\
\x74\x46\xdd\xff\x15\xa6\x6c\x84\x37\xfd\xa0\x6c\x18\x11\xe7\x78\
\x54\xa3\x72\x03\x5a\x2e\x22\x28\x86\xea\x22\x30\xed\x17\xc6\x4c\
\x84\xa6\x1d\xb5\x77\x7d\x05\x01\xc5\x0d\x0b\x70\xe0\xcf\x09\x04\
\xc4\x67\x92\x89\xdb\x31\x02\xf5\x71\x97\x17\x95\x0b\x71\xd1\xcd\
\x57\x2b\xef\x21\xdf\x6a\xef\x94\x17\xc9\xa3\xf7\xb1\x3d\xdb\x4a\
\xef\x47\xb5\xf2\x3e\x16\x6a\x5d\x79\x09\xc0\xaf\xac\x4b\x35\xb4\
\xcb\x36\x17\x5f\x78\x8c\x77\xc9\x72\x06\xe0\x08\xa0\x43\xe4\x13\
\x1f\x30\x5a\xbd\xd3\x33\x3d\xcb\x8f\x7d\xe8\xd7\xd8\xdc\x3a\x14\
\x1a\xfb\x00\x36\x13\xce\x05\x87\x1a\x0d\x1a\x6d\x27\x72\xa0\xe4\
\x32\x60\xe4\x54\x38\xd0\x70\xa2\x00\x40\x09\x08\x0c\x11\x07\x4d\
\xe6\xb8\xdd\x5d\x6f\xa8\xd3\x9f\xe3\x9e\xd8\xce\xed\x8f\xd9\x39\
\x78\x6e\x67\x39\xd6\xc8\x59\x3c\x31\xa3\x67\xc4\x4a\xad\x89\xf1\
\xa2\xce\x89\xd2\x4b\xe0\x02\xce\xec\x4e\x63\x52\x7e\xbc\x2e\xaf\
\x6b\xdc\xd6\x53\x93\x72\xd3\x60\x43\x2f\x6d\x5c\xca\x7b\x0a\x96\
\xb3\x00\x4b\xe3\x56\xb3\x4e\x61\xd3\x64\x4a\x48\x5b\xf3\xd0\xcb\
\xb1\xfa\xb1\xd8\xa7\xda\x64\xcd\x57\x28\x01\x6d\x9a\x0f\xc9\xbe\
\x49\x73\x0e\x6c\x62\x2e\x22\x5f\x95\xeb\x75\x7a\xff\xce\x5c\xef\
\x51\xce\xdb\x1f\x1c\xa3\xef\x88\xaa\x88\xfa\x4d\xd6\x10\xea\xe3\
\xb4\x07\xd6\xe5\x84\x61\xca\x4c\x7e\x73\xea\x8b\x80\x43\xab\xd1\
\xbb\xb3\x62\xa0\x32\x38\x8b\x84\xa4\x80\xb5\xfa\x4b\x14\x0d\x6f\
\x67\xcf\xb3\x08\x2a\x64\x81\x25\x25\x73\xdb\xff\xd4\x69\x44\x18\
\xa2\xbe\x84\x9c\x72\x09\x47\x2c\x10\x21\x70\x23\x43\x12\x68\x1c\
\x86\xda\x66\x4b\xf6\x86\x48\x88\xa4\x08\x19\x35\x69\x64\xc5\x2e\
\x1c\x11\x81\x4f\x68\x7f\xc8\x4e\xc1\xe6\x53\x59\x6b\xa4\xb5\x11\
\x58\x31\x75\x46\x33\xa8\xd3\xda\x60\x60\xc3\x4a\x1b\x0b\x44\x3a\
\xcf\xd7\x44\x2f\x67\x51\xa7\x71\x31\x8d\xc6\xcd\xe4\xf3\x3c\x1a\
\xf5\x8a\xcf\x12\x69\xdc\x36\x0e\x12\xc9\xbf\x90\x48\x50\x4e\xbe\
\x7f\x37\xee\xfb\x6e\x9f\x67\x56\x9b\x47\x06\xa7\xaf\xc3\xd5\x9d\
\xb7\xf9\x16\x45\xc4\x74\x19\x41\x5f\x2c\x22\x80\x0e\xfd\x30\xc0\
\x00\x57\x88\x3c\x30\x47\x80\x21\x80\x75\xab\x06\xb8\xa5\xd0\x96\
\x61\x98\xe1\xa4\x0e\xc0\x9a\x30\x0e\xd4\x08\x48\x86\x92\x43\x84\
\xa1\x43\xe0\x74\xe0\xe6\x0e\xe0\x43\x10\x83\x52\x24\x24\xa0\x27\
\x08\x31\x43\x4c\x20\xce\x38\xa6\x17\x6a\x0d\x53\x5f\x48\x4b\x3c\
\x57\xca\x0d\xdc\xbf\xde\xa8\xf8\xe8\x9b\x04\x6f\x39\x57\x16\xf2\
\x56\xa4\x35\xc4\x1d\x46\xe6\x2b\x9d\x24\x58\xbe\x65\x4d\xda\x07\
\xd3\x76\x1a\x39\x14\x49\x28\x95\x4c\xfd\xc6\x20\x2d\x79\x08\xdc\
\x02\x80\x09\x78\x48\xa4\x04\xee\x31\x65\x38\x38\xcf\x1c\xd2\xe6\
\xfb\x31\xf1\x25\xfb\x33\xf0\x21\x6c\xac\xfe\xba\xf8\x18\x36\x6f\
\x93\x68\x21\x54\x76\xd7\xb8\x22\xf8\x63\x40\xb2\x8c\xca\x7b\x4c\
\x5c\x73\x0e\x90\x09\x87\x7a\xc5\x0f\xe6\x44\xc2\x01\x01\x25\x0d\
\x9b\xe8\x5c\x26\x31\x30\xc1\xc1\xe6\x7f\xa9\x46\x1c\x7c\xde\x8b\
\x7e\xd2\x80\xe4\xf8\x65\xd4\xfc\x05\x9a\x98\xfa\xa0\xb9\x33\x5f\
\x57\xee\x6f\xfe\x07\xcd\x1d\xa1\x65\
\x00\x00\x06\xd1\
\x00\
\x00\x27\xd8\x78\x9c\xed\x59\x5b\x6f\xe3\xb6\x12\x7e\xcf\xaf\xd0\
@ -33405,10 +33670,19 @@ qt_resource_name = "\
\x00\x72\x00\x63\x00\x68\x00\x5f\x00\x42\x00\x75\x00\x69\x00\x6c\x00\x64\x00\x69\x00\x6e\x00\x67\x00\x2e\x00\x73\x00\x76\x00\x67\
\
\x00\x13\
\x06\x64\xa3\x67\
\x00\x41\
\x00\x72\x00\x63\x00\x68\x00\x5f\x00\x53\x00\x70\x00\x61\x00\x63\x00\x65\x00\x5f\x00\x54\x00\x72\x00\x65\x00\x65\x00\x2e\x00\x73\
\x00\x76\x00\x67\
\x00\x13\
\x08\x0a\x92\x67\
\x00\x41\
\x00\x72\x00\x63\x00\x68\x00\x5f\x00\x4d\x00\x65\x00\x72\x00\x67\x00\x65\x00\x57\x00\x61\x00\x6c\x00\x6c\x00\x73\x00\x2e\x00\x73\
\x00\x76\x00\x67\
\x00\x0e\
\x06\xac\xdc\x27\
\x00\x41\
\x00\x72\x00\x63\x00\x68\x00\x5f\x00\x53\x00\x70\x00\x61\x00\x63\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\
\x00\x14\
\x03\x50\x84\x07\
\x00\x70\
@ -33457,8 +33731,8 @@ qt_resource_name = "\
qt_resource_struct = "\
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x01\
\x00\x00\x00\x10\x00\x02\x00\x00\x00\x01\x00\x00\x00\x3b\
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x20\x00\x00\x00\x1b\
\x00\x00\x00\x10\x00\x02\x00\x00\x00\x01\x00\x00\x00\x3d\
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x22\x00\x00\x00\x1b\
\x00\x00\x00\x1a\x00\x02\x00\x00\x00\x17\x00\x00\x00\x04\
\x00\x00\x01\x2e\x00\x00\x00\x00\x00\x01\x00\x02\x9d\x23\
\x00\x00\x02\x92\x00\x00\x00\x00\x00\x01\x00\x06\x6c\x9e\
@ -33483,38 +33757,40 @@ qt_resource_struct = "\
\x00\x00\x01\x14\x00\x00\x00\x00\x00\x01\x00\x02\x52\xbc\
\x00\x00\x00\xe0\x00\x00\x00\x00\x00\x01\x00\x01\xbc\xaa\
\x00\x00\x02\x3e\x00\x00\x00\x00\x00\x01\x00\x05\x84\xf1\
\x00\x00\x05\x56\x00\x01\x00\x00\x00\x01\x00\x07\x5b\xb5\
\x00\x00\x06\xbc\x00\x01\x00\x00\x00\x01\x00\x07\xb3\x28\
\x00\x00\x05\x9c\x00\x00\x00\x00\x00\x01\x00\x07\x6a\x2c\
\x00\x00\x04\x12\x00\x00\x00\x00\x00\x01\x00\x07\x05\x81\
\x00\x00\x07\xec\x00\x01\x00\x00\x00\x01\x00\x08\x0a\xfd\
\x00\x00\x06\x8e\x00\x01\x00\x00\x00\x01\x00\x07\xac\x53\
\x00\x00\x04\x4c\x00\x01\x00\x00\x00\x01\x00\x07\x13\xf0\
\x00\x00\x04\x9e\x00\x01\x00\x00\x00\x01\x00\x07\x27\x77\
\x00\x00\x03\xb6\x00\x01\x00\x00\x00\x01\x00\x06\xea\xdf\
\x00\x00\x07\x86\x00\x00\x00\x00\x00\x01\x00\x07\xe7\xb9\
\x00\x00\x05\xdc\x00\x00\x00\x00\x00\x01\x00\x07\x84\x06\
\x00\x00\x05\x7c\x00\x01\x00\x00\x00\x01\x00\x07\x62\x64\
\x00\x00\x03\x94\x00\x01\x00\x00\x00\x01\x00\x06\xe1\xe6\
\x00\x00\x06\x62\x00\x01\x00\x00\x00\x01\x00\x07\xa1\x29\
\x00\x00\x03\x38\x00\x01\x00\x00\x00\x01\x00\x06\xcf\xc5\
\x00\x00\x07\x5c\x00\x01\x00\x00\x00\x01\x00\x07\xe0\x24\
\x00\x00\x04\x7a\x00\x01\x00\x00\x00\x01\x00\x07\x1d\x48\
\x00\x00\x03\x0e\x00\x01\x00\x00\x00\x01\x00\x06\xc6\x1d\
\x00\x00\x03\x74\x00\x01\x00\x00\x00\x01\x00\x06\xd9\x78\
\x00\x00\x06\x0c\x00\x01\x00\x00\x00\x01\x00\x07\x93\x74\
\x00\x00\x05\x0a\x00\x00\x00\x00\x00\x01\x00\x07\x43\x72\
\x00\x00\x06\x3a\x00\x01\x00\x00\x00\x01\x00\x07\x98\xc4\
\x00\x00\x05\x34\x00\x01\x00\x00\x00\x01\x00\x07\x53\xf3\
\x00\x00\x06\xe6\x00\x00\x00\x00\x00\x01\x00\x07\xbb\x6d\
\x00\x00\x04\xc2\x00\x01\x00\x00\x00\x01\x00\x07\x2c\x8e\
\x00\x00\x07\x30\x00\x01\x00\x00\x00\x01\x00\x07\xd7\xaa\
\x00\x00\x07\x10\x00\x01\x00\x00\x00\x01\x00\x07\xcd\x70\
\x00\x00\x05\xbc\x00\x01\x00\x00\x00\x01\x00\x07\x7d\xee\
\x00\x00\x07\xb2\x00\x00\x00\x00\x00\x01\x00\x07\xf9\x88\
\x00\x00\x03\xe8\x00\x00\x00\x00\x00\x01\x00\x06\xf3\x21\
\x00\x00\x04\xec\x00\x00\x00\x00\x00\x01\x00\x07\x34\x76\
\x00\x00\x02\xda\x00\x01\x00\x00\x00\x01\x00\x06\xbe\xcd\
\x00\x00\x05\x56\x00\x01\x00\x00\x00\x01\x00\x07\x5c\x57\
\x00\x00\x07\x0a\x00\x01\x00\x00\x00\x01\x00\x07\xc3\x7b\
\x00\x00\x05\x9c\x00\x00\x00\x00\x00\x01\x00\x07\x6a\xce\
\x00\x00\x04\x12\x00\x00\x00\x00\x00\x01\x00\x07\x06\x23\
\x00\x00\x08\x3a\x00\x01\x00\x00\x00\x01\x00\x08\x1b\x50\
\x00\x00\x06\xdc\x00\x01\x00\x00\x00\x01\x00\x07\xbc\xa6\
\x00\x00\x04\x4c\x00\x01\x00\x00\x00\x01\x00\x07\x14\x92\
\x00\x00\x04\x9e\x00\x01\x00\x00\x00\x01\x00\x07\x28\x19\
\x00\x00\x03\xb6\x00\x01\x00\x00\x00\x01\x00\x06\xeb\x81\
\x00\x00\x07\xd4\x00\x00\x00\x00\x00\x01\x00\x07\xf8\x0c\
\x00\x00\x06\x62\x00\x01\x00\x00\x00\x01\x00\x07\xa1\xcb\
\x00\x00\x06\xba\x00\x01\x00\x00\x00\x01\x00\x07\xb3\xb8\
\x00\x00\x05\xdc\x00\x00\x00\x00\x00\x01\x00\x07\x84\xa8\
\x00\x00\x05\x7c\x00\x01\x00\x00\x00\x01\x00\x07\x63\x06\
\x00\x00\x03\x94\x00\x01\x00\x00\x00\x01\x00\x06\xe2\x88\
\x00\x00\x06\x8e\x00\x01\x00\x00\x00\x01\x00\x07\xa8\x8e\
\x00\x00\x03\x38\x00\x01\x00\x00\x00\x01\x00\x06\xd0\x67\
\x00\x00\x07\xaa\x00\x01\x00\x00\x00\x01\x00\x07\xf0\x77\
\x00\x00\x04\x7a\x00\x01\x00\x00\x00\x01\x00\x07\x1d\xea\
\x00\x00\x03\x0e\x00\x01\x00\x00\x00\x01\x00\x06\xc6\xbf\
\x00\x00\x03\x74\x00\x01\x00\x00\x00\x01\x00\x06\xda\x1a\
\x00\x00\x06\x0c\x00\x01\x00\x00\x00\x01\x00\x07\x94\x16\
\x00\x00\x05\x0a\x00\x00\x00\x00\x00\x01\x00\x07\x44\x14\
\x00\x00\x06\x3a\x00\x01\x00\x00\x00\x01\x00\x07\x99\x66\
\x00\x00\x05\x34\x00\x01\x00\x00\x00\x01\x00\x07\x54\x95\
\x00\x00\x07\x34\x00\x00\x00\x00\x00\x01\x00\x07\xcb\xc0\
\x00\x00\x04\xc2\x00\x01\x00\x00\x00\x01\x00\x07\x2d\x30\
\x00\x00\x07\x7e\x00\x01\x00\x00\x00\x01\x00\x07\xe7\xfd\
\x00\x00\x07\x5e\x00\x01\x00\x00\x00\x01\x00\x07\xdd\xc3\
\x00\x00\x05\xbc\x00\x01\x00\x00\x00\x01\x00\x07\x7e\x90\
\x00\x00\x08\x00\x00\x00\x00\x00\x00\x01\x00\x08\x09\xdb\
\x00\x00\x03\xe8\x00\x00\x00\x00\x00\x01\x00\x06\xf3\xc3\
\x00\x00\x04\xec\x00\x00\x00\x00\x00\x01\x00\x07\x35\x18\
\x00\x00\x02\xda\x00\x01\x00\x00\x00\x01\x00\x06\xbf\x6f\
\x00\x00\x02\xb2\x00\x01\x00\x00\x00\x01\x00\x06\xb6\xfd\
"

View File

@ -21,6 +21,8 @@ SET(Arch_SRCS
ArchVRM.py
ArchRoof.py
importWebGL.py
ArchSpace.py
TestArch.py
)
SOURCE_GROUP("" FILES ${Arch_SRCS})

View File

@ -72,8 +72,8 @@ class ArchWorkbench(Workbench):
self.archtools = ["Arch_Wall","Arch_Structure",
"Arch_Floor","Arch_Building","Arch_Site",
"Arch_Window","Arch_Roof","Arch_Axis",
"Arch_SectionPlane","Arch_Add","Arch_Remove",
"Arch_Fixture"]
"Arch_SectionPlane","Arch_Space","Arch_Add",
"Arch_Remove","Arch_Fixture"]
self.meshtools = ["Arch_SplitMesh","Arch_MeshToShape",
"Arch_SelectNonSolidMeshes","Arch_RemoveShape",
"Arch_CloseHoles","Arch_MergeWalls"]
@ -85,13 +85,14 @@ class ArchWorkbench(Workbench):
"Draft_Dimension", "Draft_BSpline","Draft_Point"]
self.draftmodtools = ["Draft_Move","Draft_Rotate","Draft_Offset",
"Draft_Trimex", "Draft_Upgrade", "Draft_Downgrade", "Draft_Scale",
"Draft_Drawing","Draft_Edit","Draft_WireToBSpline","Draft_AddPoint",
"Draft_DelPoint","Draft_Shape2DView","Draft_Draft2Sketch","Draft_Array",
"Draft_Clone","Draft_Heal"]
"Draft_Drawing","Draft_Edit","Draft_Shape2DView","Draft_Draft2Sketch","Draft_Array",
"Draft_Clone"]
self.extramodtools = ["Draft_WireToBSpline","Draft_AddPoint","Draft_DelPoint"]
self.draftcontexttools = ["Draft_ApplyStyle","Draft_ToggleDisplayMode","Draft_AddToGroup",
"Draft_SelectGroup","Draft_SelectPlane","Draft_ToggleSnap",
"Draft_SelectGroup","Draft_SelectPlane",
"Draft_ShowSnapBar","Draft_ToggleGrid","Draft_UndoLine",
"Draft_FinishLine","Draft_CloseLine"]
self.draftutils = ["Draft_Heal"]
self.snapList = ['Draft_Snap_Lock','Draft_Snap_Midpoint','Draft_Snap_Perpendicular',
'Draft_Snap_Grid','Draft_Snap_Intersection','Draft_Snap_Parallel',
'Draft_Snap_Endpoint','Draft_Snap_Angle','Draft_Snap_Center',
@ -103,8 +104,9 @@ class ArchWorkbench(Workbench):
self.appendMenu([str(translate("arch","&Architecture")),str(translate("arch","Conversion Tools"))],self.meshtools)
self.appendMenu([str(translate("arch","&Architecture")),str(translate("arch","Calculation Tools"))],self.calctools)
self.appendMenu(str(translate("arch","&Architecture")),self.archtools)
self.appendMenu(str(translate("arch","&Draft")),self.drafttools+self.draftmodtools)
self.appendMenu(str(translate("arch","&Draft")),self.drafttools+self.draftmodtools+self.extramodtools)
self.appendMenu([str(translate("arch","&Draft")),str(translate("arch","Context Tools"))],self.draftcontexttools)
self.appendMenu([str(translate("arch","&Draft")),str(translate("arch","Utilities"))],self.draftutils)
self.appendMenu([str(translate("arch","&Draft")),str(translate("arch","Snapping"))],self.snapList)
FreeCADGui.addIconPath(":/icons")
FreeCADGui.addLanguagePath(":/translations")
@ -112,6 +114,7 @@ class ArchWorkbench(Workbench):
if hasattr(FreeCADGui,"draftToolBar"):
if not hasattr(FreeCADGui.draftToolBar,"loadedPreferences"):
FreeCADGui.addPreferencePage(":/ui/userprefs-base.ui","Draft")
FreeCADGui.addPreferencePage(":/ui/userprefs-visual.ui","Draft")
FreeCADGui.addPreferencePage(":/ui/userprefs-import.ui","Draft")
FreeCADGui.draftToolBar.loadedPreferences = True
Log ('Loading Arch module... done\n')
@ -142,14 +145,7 @@ FreeCADGui.addWorkbench(ArchWorkbench)
FreeCAD.addImportType("Industry Foundation Classes (*.ifc)","importIFC")
FreeCAD.addExportType("Wavefront OBJ - Arch module (*.obj)","importOBJ")
FreeCAD.addExportType("WebGL file (*.html)","importWebGL")
FreeCAD.addImportType("Collada (*.dae)","importDAE")
FreeCAD.addExportType("Collada (*.dae)","importDAE")
# check for pycollada
try:
import collada
except:
from DraftTools import translate
FreeCAD.Console.PrintMessage(str(translate("arch","pycollada not found, collada support will be disabled.\n")))
else:
FreeCAD.addImportType("Collada (*.dae)","importDAE")
FreeCAD.addExportType("Collada (*.dae)","importDAE")

View File

@ -32,6 +32,8 @@
<file>icons/Arch_MergeWalls.svg</file>
<file>icons/Arch_Wall_Tree_Assembly.svg</file>
<file>icons/Arch_Fixture.svg</file>
<file>icons/Arch_Space.svg</file>
<file>icons/Arch_Space_Tree.svg</file>
<file>ui/archprefs-base.ui</file>
<file>translations/Arch_af.qm</file>
<file>translations/Arch_de.qm</file>

View File

@ -0,0 +1,202 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="64px"
height="64px"
id="svg2860"
sodipodi:version="0.32"
inkscape:version="0.48.4 r9939"
sodipodi:docname="Part_Box.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape"
version="1.1">
<defs
id="defs2862">
<linearGradient
id="linearGradient3377">
<stop
id="stop3379"
offset="0"
style="stop-color:#faff2b;stop-opacity:1;" />
<stop
id="stop3381"
offset="1"
style="stop-color:#ffaa00;stop-opacity:1;" />
</linearGradient>
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 32 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="64 : 32 : 1"
inkscape:persp3d-origin="32 : 21.333333 : 1"
id="perspective2868" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3377"
id="radialGradient3092"
gradientUnits="userSpaceOnUse"
cx="45.883327"
cy="28.869568"
fx="45.883327"
fy="28.869568"
r="19.467436"
gradientTransform="matrix(1.0625325,0,0,1.0625325,-134.54016,-74.193042)" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3377-1"
id="radialGradient3095-6"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.0352785,0.23911008,-0.49121993,2.1268424,-83.020566,-210.19595)"
cx="135.38333"
cy="97.369568"
fx="135.38333"
fy="97.369568"
r="19.467436" />
<linearGradient
id="linearGradient3377-1">
<stop
id="stop3379-1"
offset="0"
style="stop-color:#faff2b;stop-opacity:1;" />
<stop
id="stop3381-0"
offset="1"
style="stop-color:#ffaa00;stop-opacity:1;" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3144"
id="radialGradient4108"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.6985294,0,202.82863)"
cx="225.26402"
cy="672.79736"
fx="225.26402"
fy="672.79736"
r="34.345188" />
<linearGradient
inkscape:collect="always"
id="linearGradient3144">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop3146" />
<stop
style="stop-color:#ffffff;stop-opacity:0;"
offset="1"
id="stop3148" />
</linearGradient>
<radialGradient
r="34.345188"
fy="672.79736"
fx="225.26402"
cy="672.79736"
cx="225.26402"
gradientTransform="matrix(1,0,0,0.6985294,0,202.82863)"
gradientUnits="userSpaceOnUse"
id="radialGradient4134"
xlink:href="#linearGradient3144"
inkscape:collect="always" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="5.5"
inkscape:cx="59.251489"
inkscape:cy="30.397505"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:document-units="px"
inkscape:grid-bbox="true"
inkscape:window-width="1920"
inkscape:window-height="1057"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:object-paths="false"
inkscape:snap-nodes="true"
inkscape:object-nodes="true"
inkscape:window-maximized="1" />
<metadata
id="metadata2865">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer">
<path
style="fill:none;stroke:#ffb300;stroke-width:2.338;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1;color:#000000;stroke-miterlimit:4;stroke-dasharray:4.676,2.338;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="M 27.763517,42.640911 6.6946913,53.073215"
id="path3903"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccc"
id="rect3520-0"
d="M 27.90216,8.2725651 57.288145,10.80966 56.820461,47.066527 27.763517,42.640911 z"
style="fill:none;stroke:#ffb300;stroke-width:2.338;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:4.676,2.338;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<g
id="g3160"
transform="matrix(-0.16208637,-0.0036825,0.0036825,-0.16208637,62.737074,142.43936)"
inkscape:export-filename="/home/yorik/Documents/Lab/Draft/icons/line.png"
inkscape:export-xdpi="7.0721951"
inkscape:export-ydpi="7.0721951">
<path
d="m 245.71428,655.2193 c 0,26.82526 -21.74617,48.57143 -48.57143,48.57143 -26.82526,0 -48.57143,-21.74617 -48.57143,-48.57143 0,-26.82526 21.74617,-48.57143 48.57143,-48.57143 26.82526,0 48.57143,21.74617 48.57143,48.57143 z"
sodipodi:ry="48.57143"
sodipodi:rx="48.57143"
sodipodi:cy="655.2193"
sodipodi:cx="197.14285"
id="path3162"
style="fill:#ffa900;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:5.80000019;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
sodipodi:type="arc" />
<path
transform="matrix(0.8513023,-0.5246754,0.5246754,0.8513023,-338.69692,214.19328)"
d="m 259.60921,672.79736 c 0,13.24993 -15.37686,23.99113 -34.34519,23.99113 -18.96832,0 -34.34519,-10.7412 -34.34519,-23.99113 0,-13.24993 15.37687,-23.99112 34.34519,-23.99112 18.96833,0 34.34519,10.74119 34.34519,23.99112 z"
sodipodi:ry="23.991123"
sodipodi:rx="34.345188"
sodipodi:cy="672.79736"
sodipodi:cx="225.26402"
id="path3164"
style="fill:url(#radialGradient4134);fill-opacity:1;stroke:none"
sodipodi:type="arc" />
</g>
<path
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccc"
id="rect3522"
d="M 27.90216,8.2725651 6.8487054,15.900709 39.25123,20.30902 l 0.513543,38.145688 17.055688,-11.388181 0.61188,-36.53502 z"
style="fill:#ffb900;stroke:#ffb300;stroke-width:2.33800000000000008;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:4.67600000000000016, 2.33800000000000008;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;fill-opacity:0.41089109" />
<path
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccc"
id="rect3520"
d="m 6.8487054,15.900709 32.9160676,3.7958 0,38.758199 -33.0700817,-5.381493 z"
style="fill:#ffb900;stroke:#ffb300;stroke-width:2.33800006000000016;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:4.67600000000000016, 2.33800000000000008;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;color:#000000;fill-opacity:0.41089112999999999;fill-rule:nonzero" />
<path
inkscape:connector-curvature="0"
id="path3536"
d="M 39.516247,19.744283 57.288145,10.80966"
style="fill:url(#radialGradient3092);fill-opacity:1;fill-rule:evenodd;stroke:#ffb300;stroke-width:2.338;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:4.676,2.338;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 8.4 KiB

View File

@ -0,0 +1,165 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="64px"
height="64px"
id="svg2860"
sodipodi:version="0.32"
inkscape:version="0.48.4 r9939"
sodipodi:docname="Arch_Space.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape"
version="1.1">
<defs
id="defs2862">
<linearGradient
id="linearGradient3377">
<stop
id="stop3379"
offset="0"
style="stop-color:#faff2b;stop-opacity:1;" />
<stop
id="stop3381"
offset="1"
style="stop-color:#ffaa00;stop-opacity:1;" />
</linearGradient>
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 32 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="64 : 32 : 1"
inkscape:persp3d-origin="32 : 21.333333 : 1"
id="perspective2868" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3377-1"
id="radialGradient3095-6"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.0352785,0.23911008,-0.49121993,2.1268424,-83.020566,-210.19595)"
cx="135.38333"
cy="97.369568"
fx="135.38333"
fy="97.369568"
r="19.467436" />
<linearGradient
id="linearGradient3377-1">
<stop
id="stop3379-1"
offset="0"
style="stop-color:#faff2b;stop-opacity:1;" />
<stop
id="stop3381-0"
offset="1"
style="stop-color:#ffaa00;stop-opacity:1;" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3144"
id="radialGradient4108"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.6985294,0,202.82863)"
cx="225.26402"
cy="672.79736"
fx="225.26402"
fy="672.79736"
r="34.345188" />
<linearGradient
inkscape:collect="always"
id="linearGradient3144">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop3146" />
<stop
style="stop-color:#ffffff;stop-opacity:0;"
offset="1"
id="stop3148" />
</linearGradient>
<radialGradient
r="34.345188"
fy="672.79736"
fx="225.26402"
cy="672.79736"
cx="225.26402"
gradientTransform="matrix(1,0,0,0.6985294,0,202.82863)"
gradientUnits="userSpaceOnUse"
id="radialGradient4134"
xlink:href="#linearGradient3144"
inkscape:collect="always" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="3.8890873"
inkscape:cx="23.686232"
inkscape:cy="16.197092"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:document-units="px"
inkscape:grid-bbox="true"
inkscape:window-width="1920"
inkscape:window-height="1057"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:object-paths="false"
inkscape:snap-nodes="true"
inkscape:object-nodes="true"
inkscape:window-maximized="1" />
<metadata
id="metadata2865">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer">
<path
style="color:#000000;fill:#ffffff;stroke:#858585;stroke-width:4;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:8,4;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;fill-opacity:0.41089118000000002"
d="M 27.316936,43.604414 4.0599801,55.120178"
id="path3903"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccc"
id="rect3520-0"
d="M 27.469977,5.6667004 59.90788,8.4672884 59.391624,48.489658 27.316936,43.604414 z"
style="fill:#ffffff;stroke:#858585;stroke-width:4;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:8,4;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;fill-opacity:0.41089118000000002" />
<path
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccc"
id="rect3522"
d="M 27.469977,5.6667004 4.2299895,14.087074 39.997719,18.953217 40.564596,61.060573 59.391624,48.489658 60.067052,8.1602475 z"
style="fill:#ffffff;fill-opacity:0.41089118000000002;stroke:#858585;stroke-width:4;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:8,4;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<path
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccc"
id="rect3520"
d="m 4.2299895,14.087074 36.3346065,4.190018 0,42.783481 -36.5046159,-5.940395 z"
style="color:#000000;fill:#ffffff;fill-opacity:0.41089118000000002;fill-rule:nonzero;stroke:#858585;stroke-width:4;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:8,4;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<path
inkscape:connector-curvature="0"
id="path3536"
d="M 40.29026,18.329828 59.90788,8.4672884"
style="fill:#ffffff;fill-opacity:0.41089118000000002;fill-rule:evenodd;stroke:#858585;stroke-width:4;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:8,4;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.4 KiB

View File

@ -23,7 +23,7 @@
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>General Arch Settings</string>
<string>Default settings</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
@ -31,7 +31,7 @@
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Default color for walls</string>
<string>Wall</string>
</property>
</widget>
</item>
@ -48,6 +48,59 @@
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_10">
<property name="text">
<string>Width:</string>
</property>
</widget>
</item>
<item>
<widget class="Gui::PrefDoubleSpinBox" name="gui::prefdoublespinbox_2">
<property name="maximum">
<double>9999.989999999999782</double>
</property>
<property name="value">
<double>200.000000000000000</double>
</property>
<property name="prefEntry" stdset="0">
<cstring>WallWidth</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Arch</cstring>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_8">
<property name="text">
<string>Height:</string>
</property>
</widget>
</item>
<item>
<widget class="Gui::PrefDoubleSpinBox" name="gui::prefdoublespinbox_3">
<property name="maximum">
<double>9999.989999999999782</double>
</property>
<property name="value">
<double>3000.000000000000000</double>
</property>
<property name="prefEntry" stdset="0">
<cstring>WallHeight</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Arch</cstring>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_9">
<property name="text">
<string>Color:</string>
</property>
</widget>
</item>
<item>
<widget class="Gui::PrefColorButton" name="gui::prefcolorbutton">
<property name="toolTip">
@ -75,7 +128,7 @@
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Default color for structures</string>
<string>Structure</string>
</property>
</widget>
</item>
@ -92,6 +145,82 @@
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_12">
<property name="text">
<string>Length:</string>
</property>
</widget>
</item>
<item>
<widget class="Gui::PrefDoubleSpinBox" name="gui::prefdoublespinbox_4">
<property name="maximum">
<double>9999.989999999999782</double>
</property>
<property name="value">
<double>100.000000000000000</double>
</property>
<property name="prefEntry" stdset="0">
<cstring>StructureLength</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Arch</cstring>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_13">
<property name="text">
<string>Width:</string>
</property>
</widget>
</item>
<item>
<widget class="Gui::PrefDoubleSpinBox" name="gui::prefdoublespinbox_5">
<property name="maximum">
<double>9999.989999999999782</double>
</property>
<property name="value">
<double>100.000000000000000</double>
</property>
<property name="prefEntry" stdset="0">
<cstring>StructureWidth</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Arch</cstring>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_14">
<property name="text">
<string>Height:</string>
</property>
</widget>
</item>
<item>
<widget class="Gui::PrefDoubleSpinBox" name="gui::prefdoublespinbox_6">
<property name="maximum">
<double>9999.989999999999782</double>
</property>
<property name="value">
<double>1000.000000000000000</double>
</property>
<property name="prefEntry" stdset="0">
<cstring>StructureHeight</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Arch</cstring>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_11">
<property name="text">
<string>Color:</string>
</property>
</widget>
</item>
<item>
<widget class="Gui::PrefColorButton" name="gui::prefcolorbutton_2">
<property name="toolTip">
@ -119,7 +248,7 @@
<item>
<widget class="QLabel" name="label_5">
<property name="text">
<string>Default color for windows</string>
<string>Window</string>
</property>
</widget>
</item>
@ -136,6 +265,13 @@
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_6">
<property name="text">
<string>Frame color:</string>
</property>
</widget>
</item>
<item>
<widget class="Gui::PrefColorButton" name="gui::prefcolorbutton_3">
<property name="color">
@ -153,30 +289,13 @@
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_14">
<item>
<widget class="QLabel" name="label_6">
<widget class="QLabel" name="label_15">
<property name="text">
<string>Default color for window glass</string>
<string>Glass color:</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="Gui::PrefColorButton" name="gui::prefcolorbutton_4">
<property name="color">
@ -285,23 +404,6 @@
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="Gui::PrefCheckBox" name="gui::prefcheckbox_3">
<property name="text">
<string>Import furniture (can make the model heavy)</string>
</property>
<property name="prefEntry" stdset="0">
<cstring>importIfcFurniture</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Arch</cstring>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_11">
<item>
@ -360,7 +462,7 @@
<string/>
</property>
<property name="placeholderText">
<string>IfcSpace,IfcBuildingElementProxy,IfcFlowTerminal</string>
<string>IfcSpace,IfcBuildingElementProxy,IfcFlowTerminal,IfcFurnishingElement</string>
</property>
<property name="prefEntry" stdset="0">
<cstring>ifcSkip</cstring>
@ -372,6 +474,33 @@
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_16">
<item>
<widget class="QLabel" name="label_7">
<property name="text">
<string>Import as meshes:</string>
</property>
</widget>
</item>
<item>
<widget class="Gui::PrefLineEdit" name="gui::preflineedit_2">
<property name="toolTip">
<string>A comma-separated list of IFC types that must be imported as meshes</string>
</property>
<property name="placeholderText">
<string>IfcFurnishingElement</string>
</property>
<property name="prefEntry" stdset="0">
<cstring>ifcAsMesh</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Arch</cstring>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
@ -441,22 +570,22 @@
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<layoutdefault spacing="6" margin="11"/>

53
src/Mod/Arch/TestArch.py Normal file
View File

@ -0,0 +1,53 @@
# Unit test for the Arch module
#***************************************************************************
#* (c) Yorik van Havre <yorik@uncreated.net> 2013 *
#* *
#* 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 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 *
#* *
#***************************************************************************/
import FreeCAD, os, unittest, FreeCADGui, Arch, Draft
class ArchTest(unittest.TestCase):
def setUp(self):
# setting a new document to hold the tests
if FreeCAD.ActiveDocument:
if FreeCAD.ActiveDocument.Name != "ArchTest":
FreeCAD.newDocument("ArchTest")
else:
FreeCAD.newDocument("ArchTest")
FreeCAD.setActiveDocument("ArchTest")
def testWall(self):
FreeCAD.Console.PrintLog ('Checking Arch Wall...\n')
l=Draft.makeLine(FreeCAD.Vector(0,0,0),FreeCAD.Vector(-2,0,0))
w = Arch.makeWall(l)
self.failUnless(w,"Arch Wall failed")
def testStructure(self):
FreeCAD.Console.PrintLog ('Checking Arch Structure...\n')
s = Arch.makeStructure(length=2,width=3,hright=5)
self.failUnless(s,"Arch Structure failed")
def tearDown(self):
FreeCAD.closeDocument("ArchTest")
pass

View File

@ -37,14 +37,15 @@ def checkCollada():
try:
import collada
except:
FreeCAD.Console.PrintError(str(translate("Arch","pycollada not found, no collada support.\n")))
FreeCAD.Console.PrintError(str(translate("Arch","pycollada not found, collada support is disabled.\n")))
return False
else:
return True
def open(filename):
"called when freecad wants to open a file"
if not checkCollada(): return
if not checkCollada():
return
docname = os.path.splitext(os.path.basename(filename))[0]
doc = FreeCAD.newDocument(docname)
doc.Label = decode(docname)
@ -54,7 +55,8 @@ def open(filename):
def insert(filename,docname):
"called when freecad wants to import a file"
if not checkCollada(): return
if not checkCollada():
return
try:
doc = FreeCAD.getDocument(docname)
except:

View File

@ -59,17 +59,17 @@ def insert(filename,docname):
def getConfig():
"Gets Arch IFC import preferences"
global CREATE_IFC_GROUPS, IMPORT_IFC_FURNITURE, DEBUG, SKIP, PREFIX_NUMBERS, FORCE_PYTHON_PARSER, SEPARATE_OPENINGS
global CREATE_IFC_GROUPS, ASMESH, DEBUG, SKIP, PREFIX_NUMBERS, FORCE_PYTHON_PARSER, SEPARATE_OPENINGS
CREATE_IFC_GROUPS = False
IMPORT_IFC_FURNITURE = False
DEBUG = False
SKIP = ["IfcSpace","IfcBuildingElementProxy","IfcFlowTerminal"]
SKIP = ["IfcBuildingElementProxy","IfcFlowTerminal","IfcFurnishingElement"]
ASMESH = ["IfcFurnishingElement"]
PREFIX_NUMBERS = False
FORCE_PYTHON_PARSER = False
SEPARATE_OPENINGS = False
p = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Arch")
CREATE_IFC_GROUPS = p.GetBool("createIfcGroups")
IMPORT_IFC_FURNITURE = p.GetBool("importIfcFurniture")
FORCE_PYTHON_PARSER = p.GetBool("forceIfcPythonParser")
DEBUG = p.GetBool("ifcDebug")
SEPARATE_OPENINGS = p.GetBool("ifcSeparateOpenings")
@ -77,7 +77,9 @@ def getConfig():
skiplist = p.GetString("ifcSkip")
if skiplist:
SKIP = skiplist.split(",")
asmeshlist = p.GetString("ifcAsMesh")
if asmeshlist:
ASMESH = asmeshlist.split(",")
def getIfcOpenShell():
"locates and imports ifcopenshell"
@ -104,8 +106,6 @@ def read(filename):
if DEBUG: global ifcObjects,ifcParents
ifcObjects = {} # a table to relate ifc id with freecad object
ifcParents = {} # a table to relate ifc id with parent id
if not IMPORT_IFC_FURNITURE:
SKIP.append("IfcFurnishingElement")
if hasattr(IfcImport,"DISABLE_OPENING_SUBTRACTIONS") and SEPARATE_OPENINGS:
IfcImport.Settings(IfcImport.DISABLE_OPENING_SUBTRACTIONS,True)
else:
@ -123,7 +123,6 @@ def read(filename):
obj = IfcImport.Get()
if DEBUG: print "["+str(int((float(obj.id)/num_lines)*100))+"%] parsing ",obj.id,": ",obj.name," of type ",obj.type
meshdata = []
# retrieving name
n = getName(obj)
@ -164,6 +163,10 @@ def read(filename):
elif obj.type in ["IfcSite"]:
nobj = makeSite(obj.id,shape,n)
# spaces
elif obj.type in ["IfcSpace"]:
nobj = makeSpace(obj.id,shape,n)
elif shape:
# treat as dumb parts
#if DEBUG: print "Fixme: Shape-containing object not handled: ",obj.id, " ", obj.type
@ -185,7 +188,7 @@ def read(filename):
if not IfcImport.Next():
break
# processing non-geometry and relationships
parents_temp = dict(ifcParents)
import ArchCommands
@ -239,7 +242,7 @@ def read(filename):
ArchCommands.addComponents(ifcObjects[id],parent)
else:
ArchCommands.removeComponents(ifcObjects[id],parent)
IfcImport.CleanUp()
else:
@ -282,7 +285,7 @@ def read(filename):
for s in ifc.getEnt("IfcSite"):
group(s,ifc,"Site")
if DEBUG: print "done parsing. Recomputing..."
if DEBUG: print "done parsing. Recomputing..."
FreeCAD.ActiveDocument.recompute()
t3 = time.time()
if DEBUG: print "done processing IFC file in %s s" % ((t3-t1))
@ -306,8 +309,12 @@ def makeWall(entity,shape=None,name="Wall"):
try:
if shape:
# use ifcopenshell
body = FreeCAD.ActiveDocument.addObject("Part::Feature","WallBody")
body.Shape = shape
if isinstance(shape,Part.Shape):
body = FreeCAD.ActiveDocument.addObject("Part::Feature",name+"_body")
body.Shape = shape
else:
body = FreeCAD.ActiveDocument.addObject("Mesh::Feature",name+"_body")
body.Mesh = shape
wall = Arch.makeWall(body,name=name)
wall.Label = name
if DEBUG: print "made wall object ",entity,":",wall
@ -352,11 +359,12 @@ def makeWindow(entity,shape=None,name="Window"):
try:
if shape:
# use ifcopenshell
window = Arch.makeWindow(name=name)
window.Shape = shape
window.Label = name
if DEBUG: print "made window object ",entity,":",window
return window
if isinstance(shape,Part.Shape):
window = Arch.makeWindow(name=name)
window.Shape = shape
window.Label = name
if DEBUG: print "made window object ",entity,":",window
return window
# use internal parser
if DEBUG: print "=====> making window",entity.id
@ -386,9 +394,13 @@ def makeStructure(entity,shape=None,name="Structure"):
try:
if shape:
# use ifcopenshell
sh = FreeCAD.ActiveDocument.addObject("Part::Feature","StructureBody")
sh.Shape = shape
structure = Arch.makeStructure(sh,name=name)
if isinstance(shape,Part.Shape):
body = FreeCAD.ActiveDocument.addObject("Part::Feature",name+"_body")
body.Shape = shape
else:
body = FreeCAD.ActiveDocument.addObject("Mesh::Feature",name+"_body")
body.Mesh = shape
structure = Arch.makeStructure(body,name=name)
structure.Label = name
if DEBUG: print "made structure object ",entity,":",structure
return structure
@ -419,15 +431,37 @@ def makeStructure(entity,shape=None,name="Structure"):
def makeSite(entity,shape=None,name="Site"):
"makes a site in the freecad document"
try:
body = None
if shape:
# use ifcopenshell
site = Arch.makeSite(name=name)
site.Label = name
body = FreeCAD.ActiveDocument.addObject("Part::Feature",name+"_body")
body.Shape = shape
if isinstance(shape,Part.Shape):
body = FreeCAD.ActiveDocument.addObject("Part::Feature",name+"_body")
body.Shape = shape
else:
body = FreeCAD.ActiveDocument.addObject("Mesh::Feature",name+"_body")
body.Mesh = shape
site = Arch.makeSite(name=name)
site.Label = name
if body:
site.Terrain = body
if DEBUG: print "made site object ",entity,":",site
return site
if DEBUG: print "made site object ",entity,":",site
return site
except:
return None
def makeSpace(entity,shape=None,name="Space"):
"makes a space in the freecad document"
try:
if shape:
# use ifcopenshell
if isinstance(shape,Part.Shape):
space = Arch.makeSpace(name=name)
space.Label = name
body = FreeCAD.ActiveDocument.addObject("Part::Feature",name+"_body")
body.Shape = shape
space.Base = body
if DEBUG: print "made space object ",entity,":",space
return site
except:
return None
@ -437,11 +471,12 @@ def makeRoof(entity,shape=None,name="Roof"):
try:
if shape:
# use ifcopenshell
roof = Arch.makeRoof(name=name)
roof.Label = name
roof.Shape = shape
if DEBUG: print "made roof object ",entity,":",roof
return roof
if isinstance(shape,Part.Shape):
roof = Arch.makeRoof(name=name)
roof.Label = name
roof.Shape = shape
if DEBUG: print "made roof object ",entity,":",roof
return roof
except:
return None
@ -450,6 +485,9 @@ def makeRoof(entity,shape=None,name="Roof"):
def getMesh(obj):
"gets mesh and placement from an IfcOpenShell object"
import Mesh
meshdata = []
print obj.mesh.faces
print obj.mesh.verts
f = obj.mesh.faces
v = obj.mesh.verts
for i in range(0, len(f), 3):
@ -458,6 +496,7 @@ def getMesh(obj):
vi = f[i+j]*3
face.append([v[vi],v[vi+1],v[vi+2]])
meshdata.append(face)
print meshdata
me = Mesh.Mesh(meshdata)
# get transformation matrix
m = obj.matrix
@ -470,9 +509,15 @@ def getMesh(obj):
def getShape(obj):
"gets a shape from an IfcOpenShell object"
import StringIO,Part
#print "retrieving shape from obj ",obj.id
import Part
sh=Part.Shape()
sh.importBrep(StringIO.StringIO(obj.mesh.brep_data))
try:
sh.importBrepFromString(obj.mesh.brep_data)
#sh = Part.makeBox(2,2,2)
except:
print "Error: malformed shape"
return None
if not sh.Solids:
# try to extract a solid shape
if sh.Faces:
@ -494,6 +539,8 @@ def getShape(obj):
0, 0, 0, 1)
sh.Placement = FreeCAD.Placement(mat)
# if DEBUG: print "getting Shape from ",obj
#print "getting shape: ",sh,sh.Solids,sh.Volume,sh.isValid(),sh.isNull()
#for v in sh.Vertexes: print v.Point
return sh
# below is only used by the internal parser #########################################

View File

@ -51,5 +51,7 @@ add_subdirectory(OpenSCAD)
add_subdirectory(Plot)
add_subdirectory(Spreadsheet)

View File

@ -60,7 +60,7 @@ void AppCompleteExport initComplete()
try {
Base::Interpreter().loadModule("Draft");
}
catch (const Base::PyException& e) {
catch (const Base::Exception& e) {
// If called from console then issue a message but don't stop with an error
PySys_WriteStdout("Import error: %s\n", e.what());
}

View File

@ -140,9 +140,9 @@ Gui::MenuItem* Workbench::setupMenuBar() const
Gui::MenuItem* stdviews = new Gui::MenuItem;
stdviews->setCommand("Standard views");
*stdviews << "Std_ViewFitAll" << "Std_ViewFitSelection" << "Std_ViewAxo"
<< "Separator" << "Std_ViewFront" << "Std_ViewRight"
<< "Std_ViewTop" << "Separator" << "Std_ViewRear"
<< "Std_ViewLeft" << "Std_ViewBottom";
<< "Separator" << "Std_ViewFront" << "Std_ViewTop"
<< "Std_ViewRight" << "Separator" << "Std_ViewRear"
<< "Std_ViewBottom" << "Std_ViewLeft";
// stereo
Gui::MenuItem* view3d = new Gui::MenuItem;
@ -209,7 +209,6 @@ Gui::MenuItem* Workbench::setupMenuBar() const
mesh->setCommand("&Meshes");
*mesh << "Mesh_Import"
<< "Mesh_Export"
<< "Mesh_FromGeometry"
<< "MeshPart_Mesher"
<< "Separator"
<< analyze
@ -470,8 +469,8 @@ Gui::ToolBarItem* Workbench::setupToolBars() const
Gui::ToolBarItem* view = new Gui::ToolBarItem( root );
view->setCommand("View");
*view << "Std_ViewFitAll" << "Separator" << "Std_ViewAxo" << "Separator" << "Std_ViewFront"
<< "Std_ViewRight" << "Std_ViewTop" << "Separator" << "Std_ViewRear" << "Std_ViewLeft"
<< "Std_ViewBottom" << "Separator" << "Std_MeasureDistance";
<< "Std_ViewTop" << "Std_ViewRight" << "Separator" << "Std_ViewRear" << "Std_ViewBottom"
<< "Std_ViewLeft" << "Separator" << "Std_MeasureDistance";
// Part Design
Gui::ToolBarItem* part_design = new Gui::ToolBarItem( root );

View File

@ -17,6 +17,7 @@ SET(Draft_SRCS
importAirfoilDAT.py
macros.py
Draft_rc.py
TestDraft.py
)
SOURCE_GROUP("" FILES ${Draft_SRCS})

File diff suppressed because it is too large Load Diff

View File

@ -177,6 +177,19 @@ def geomType(edge):
return "Unknown"
except:
return "Unknown"
def isValidPath(shape):
"isValidPath(shape): returns True if the shape can be used as an extrusion path"
if shape.Faces:
return False
if len(shape.Wires) > 1:
return False
if shape.Wires:
if shape.Wires[0].isClosed():
return False
if shape.isClosed():
return False
return True
# edge functions *****************************************************************
@ -400,8 +413,8 @@ def geom(edge,plac=FreeCAD.Placement()):
c = edge.Curve.Center
cu = Part.Circle(edge.Curve.Center,normal,edge.Curve.Radius)
ref = plac.Rotation.multVec(Vector(1,0,0))
a1 = DraftVecUtils.angle(v1.sub(c),ref,DraftVecUtils.neg(normal))
a2 = DraftVecUtils.angle(v2.sub(c),ref,DraftVecUtils.neg(normal))
a1 = DraftVecUtils.angle(v1.sub(c),ref,normal.negative())
a2 = DraftVecUtils.angle(v2.sub(c),ref,normal.negative())
# direction check
if edge.Curve.Axis.getAngle(normal) > 1:
@ -418,7 +431,7 @@ def mirror (point, edge):
normPoint = point.add(findDistance(point, edge, False))
if normPoint:
normPoint_point = Vector.sub(point, normPoint)
normPoint_refl = DraftVecUtils.neg(normPoint_point)
normPoint_refl = normPoint_point.negative()
refl = Vector.add(normPoint, normPoint_refl)
return refl
else:
@ -438,7 +451,7 @@ def isClockwise(edge,ref=None):
if not ref:
ref = Vector(0,0,1)
if n.getAngle(ref) > math.pi/2:
n = DraftVecUtils.neg(n)
n = n.negative()
if DraftVecUtils.angle(v1,v2,n) < 0:
return False
if n.z < 0:
@ -721,7 +734,7 @@ def findMidpoint(edge):
if len(edge.Vertexes) == 1:
# Circle
dv = first.sub(center)
dv = DraftVecUtils.neg(dv)
dv = dv.negative()
return center.add(dv)
axis = edge.Curve.Axis
chord = last.sub(first)
@ -730,12 +743,12 @@ def findMidpoint(edge):
ray = first.sub(center)
apothem = ray.dot(perp)
sagitta = radius - apothem
startpoint = Vector.add(first, DraftVecUtils.scale(chord,0.5))
startpoint = Vector.add(first, chord.multiply(0.5))
endpoint = DraftVecUtils.scaleTo(perp,sagitta)
return Vector.add(startpoint,endpoint)
elif geomType(edge) == "Line":
halfedge = DraftVecUtils.scale(last.sub(first),.5)
halfedge = (last.sub(first)).multiply(.5)
return Vector.add(first,halfedge)
else:
@ -850,7 +863,8 @@ def getNormal(shape):
if FreeCAD.GuiUp:
import Draft
vdir = Draft.get3DView().getViewDirection()
if n.getAngle(vdir) < 0.78: n = DraftVecUtils.neg(n)
if n.getAngle(vdir) < 0.78:
n = n.negative()
return n
def getRotation(v1,v2=FreeCAD.Vector(0,0,1)):
@ -1003,7 +1017,7 @@ def findDistance(point,edge,strict=False):
center = edge.Curve.Center
segment = center.sub(point)
ratio = (segment.Length - edge.Curve.Radius) / segment.Length
dist = DraftVecUtils.scale(segment,ratio)
dist = segment.multiply(ratio)
newpoint = Vector.add(point, dist)
if (dist.Length == 0):
return None
@ -1053,7 +1067,7 @@ def angleBisection(edge1, edge2):
return Part.Line(origin,origin.add(dir)).toShape()
else:
diff = p3.sub(p1)
origin = p1.add(DraftVecUtils.scale(diff, 0.5))
origin = p1.add(diff.multiply(0.5))
dir = p2.sub(p1); dir.normalize()
return Part.Line(origin,origin.add(dir)).toShape()
else:
@ -1857,8 +1871,8 @@ def circlefrom1Line2Points(edge, p1, p2):
v2 = p2.sub(s)
projectedDist = math.sqrt(abs(v1.dot(v2)))
edgeDir = vec(edge); edgeDir.normalize()
projectedCen1 = Vector.add(s, DraftVecUtils.scale(edgeDir, projectedDist))
projectedCen2 = Vector.add(s, DraftVecUtils.scale(edgeDir, -projectedDist))
projectedCen1 = Vector.add(s, Vector(edgeDir).multiply(projectedDist))
projectedCen2 = Vector.add(s, Vector(edgeDir).multiply(-projectedDist))
perpEdgeDir = edgeDir.cross(Vector(0,0,1))
perpCen1 = Vector.add(projectedCen1, perpEdgeDir)
perpCen2 = Vector.add(projectedCen2, perpEdgeDir)
@ -1890,13 +1904,13 @@ def circleFrom2LinesRadius (edge1, edge2, radius):
dist12 = radius / math.sin(ang12 * 0.5)
dist21 = radius / math.sin(ang21 * 0.5)
circles = []
cen = Vector.add(int, DraftVecUtils.scale(vec(bis12), dist12))
cen = Vector.add(int, vec(bis12).multiply(dist12))
circles.append(Part.Circle(cen, NORM, radius))
cen = Vector.add(int, DraftVecUtils.scale(vec(bis12), -dist12))
cen = Vector.add(int, vec(bis12).multiply(-dist12))
circles.append(Part.Circle(cen, NORM, radius))
cen = Vector.add(int, DraftVecUtils.scale(vec(bis21), dist21))
cen = Vector.add(int, vec(bis21).multiply(dist21))
circles.append(Part.Circle(cen, NORM, radius))
cen = Vector.add(int, DraftVecUtils.scale(vec(bis21), -dist21))
cen = Vector.add(int, vec(bis21).multiply(-dist21))
circles.append(Part.Circle(cen, NORM, radius))
return circles
@ -1954,15 +1968,15 @@ def circleFromPointLineRadius (point, edge, radius):
if dist.Length == 0:
segment = vec(edge)
perpVec = DraftVecUtils.crossproduct(segment); perpVec.normalize()
normPoint_c1 = DraftVecUtils.scale(perpVec, radius)
normPoint_c2 = DraftVecUtils.scale(perpVec, -radius)
normPoint_c1 = Vector(perpVec).multiply(radius)
normPoint_c2 = Vector(perpVec).multiply(-radius)
center1 = point.add(normPoint_c1)
center2 = point.add(normPoint_c2)
elif dist.Length > 2 * radius:
return None
elif dist.Length == 2 * radius:
normPoint = point.add(findDistance(point, edge, False))
dummy = DraftVecUtils.scale(normPoint.sub(point), 0.5)
dummy = (normPoint.sub(point)).multiply(0.5)
cen = point.add(dummy)
circ = Part.Circle(cen, NORM, radius)
if circ:
@ -1975,8 +1989,8 @@ def circleFromPointLineRadius (point, edge, radius):
dist = math.sqrt(radius**2 - (radius - normDist)**2)
centerNormVec = DraftVecUtils.scaleTo(point.sub(normPoint), radius)
edgeDir = edge.Vertexes[0].Point.sub(normPoint); edgeDir.normalize()
center1 = centerNormVec.add(normPoint.add(DraftVecUtils.scale(edgeDir, dist)))
center2 = centerNormVec.add(normPoint.add(DraftVecUtils.scale(edgeDir, -dist)))
center1 = centerNormVec.add(normPoint.add(Vector(edgeDir).multiply(dist)))
center2 = centerNormVec.add(normPoint.add(Vector(edgeDir).multiply(-dist)))
circles = []
if center1:
circ = Part.Circle(center1, NORM, radius)
@ -2006,8 +2020,8 @@ def circleFrom2PointsRadius(p1, p2, radius):
dir = vec(p1_p2); dir.normalize()
perpDir = dir.cross(Vector(0,0,1)); perpDir.normailze()
dist = math.sqrt(radius**2 - (dist_p1p2 / 2.0)**2)
cen1 = Vector.add(mid, DraftVecUtils.scale(perpDir, dist))
cen2 = Vector.add(mid, DraftVecUtils.scale(perpDir, -dist))
cen1 = Vector.add(mid, Vector(perpDir).multiply(dist))
cen2 = Vector.add(mid, Vector(perpDir).multiply(-dist))
circles = []
if cen1: circles.append(Part.Circle(cen1, norm, radius))
if cen2: circles.append(Part.Circle(cen2, norm, radius))
@ -2252,12 +2266,12 @@ def findHomotheticCenterOfCircles(circle1, circle2):
perpCenDir = cenDir.cross(Vector(0,0,1)); perpCenDir.normalize()
# Get point on first circle
p1 = Vector.add(circle1.Curve.Center, DraftVecUtils.scale(perpCenDir, circle1.Curve.Radius))
p1 = Vector.add(circle1.Curve.Center, Vector(perpCenDir).multiply(circle1.Curve.Radius))
centers = []
# Calculate inner homothetic center
# Get point on second circle
p2_inner = Vector.add(circle1.Curve.Center, DraftVecUtils.scale(perpCenDir, -circle1.Curve.Radius))
p2_inner = Vector.add(circle1.Curve.Center, Vector(perpCenDir).multiply(-circle1.Curve.Radius))
hCenterInner = DraftVecUtils.intersect(circle1.Curve.Center, circle2.Curve.Center, p1, p2_inner, True, True)
if hCenterInner:
centers.append(hCenterInner)
@ -2265,7 +2279,7 @@ def findHomotheticCenterOfCircles(circle1, circle2):
# Calculate outer homothetic center (only exists of the circles have different radii)
if circle1.Curve.Radius != circle2.Curve.Radius:
# Get point on second circle
p2_outer = Vector.add(circle1.Curve.Center, DraftVecUtils.scale(perpCenDir, circle1.Curve.Radius))
p2_outer = Vector.add(circle1.Curve.Center, Vector(perpCenDir).multiply(circle1.Curve.Radius))
hCenterOuter = DraftVecUtils.intersect(circle1.Curve.Center, circle2.Curve.Center, p1, p2_outer, True, True)
if hCenterOuter:
centers.append(hCenterOuter)
@ -2315,7 +2329,7 @@ def findRadicalAxis(circle1, circle2):
k1 = (dist + (r1^2 - r2^2) / dist) / 2.0
#k2 = dist - k1
K = Vector.add(cen1, DraftVecUtils.scale(cenDir, k1))
K = Vector.add(cen1, cenDir.multiply(k1))
# K_ .. A point somewhere between K and J (actually with a distance of 1 unit from K).
K_ = Vector,add(K, perpCenDir)

View File

@ -978,13 +978,13 @@ class DraftToolBar:
last = self.sourceCmd.node[0]
else:
last = self.sourceCmd.node[-1]
print "last:",last
#print "last:",last
v = FreeCAD.Vector(numx,numy,numz)
print "orig:",v
#print "orig:",v
if FreeCAD.DraftWorkingPlane:
v = FreeCAD.Vector(numx,numy,numz)
v = FreeCAD.DraftWorkingPlane.getGlobalRot(v)
print "rotated:",v
#print "rotated:",v
numx = last.x + v.x
numy = last.y + v.y
numz = last.z + v.z
@ -1418,7 +1418,7 @@ class DraftToolBar:
def changeEvent(self, event):
if event.type() == QtCore.QEvent.LanguageChange:
print "Language changed!"
#print "Language changed!"
self.ui.retranslateUi(self)
def Activated(self):

View File

@ -258,7 +258,7 @@ class Snapper:
elif (Draft.getType(obj) == "Structure") and not oldActive:
# special snapping for struct: only to its base point (except when CTRL is pressed)
if obj.Base:
for edge in o.Base.Shape.Edges:
for edge in obj.Base.Shape.Edges:
snaps.extend(self.snapToEndpoints(edge))
snaps.extend(self.snapToMidpoint(edge))
snaps.extend(self.snapToPerpendicular(edge,lastpoint))
@ -466,13 +466,13 @@ class Snapper:
FreeCAD.Vector(0,0,1)]
for a in self.polarAngles:
if a == 90:
vecs.extend([ax[0],DraftVecUtils.neg(ax[0])])
vecs.extend([ax[1],DraftVecUtils.neg(ax[1])])
vecs.extend([ax[0],ax[0].negative()])
vecs.extend([ax[1],ax[1].negative()])
else:
v = DraftVecUtils.rotate(ax[0],math.radians(a),ax[2])
vecs.extend([v,DraftVecUtils.neg(v)])
vecs.extend([v,v.negative()])
v = DraftVecUtils.rotate(ax[1],math.radians(a),ax[2])
vecs.extend([v,DraftVecUtils.neg(v)])
vecs.extend([v,v.negative()])
for v in vecs:
de = Part.Line(last,last.add(v)).toShape()
np = self.getPerpendicular(de,point)
@ -1054,5 +1054,5 @@ if not hasattr(FreeCADGui,"Snapper"):
if not hasattr(FreeCAD,"DraftWorkingPlane"):
import WorkingPlane, Draft_rc
FreeCAD.DraftWorkingPlane = WorkingPlane.plane()
print FreeCAD.DraftWorkingPlane
#print FreeCAD.DraftWorkingPlane
FreeCADGui.addIconPath(":/icons")

View File

@ -232,12 +232,7 @@ class DraftTool:
self.ui.sourceCmd = self
self.ui.setTitle(name)
self.ui.show()
try:
rot = self.view.getCameraNode().getField("orientation").getValue()
upv = Vector(rot.multVec(coin.SbVec3f(0,1,0)).getValue())
plane.setup(DraftVecUtils.neg(self.view.getViewDirection()), Vector(0,0,0), upv)
except:
pass
plane.setup()
self.node = []
self.pos = []
self.constrain = None
@ -382,7 +377,7 @@ class SelectPlane(DraftTool):
self.display('side')
self.finish()
elif arg == "currentView":
viewDirection = DraftVecUtils.neg(self.view.getViewDirection())
viewDirection = self.view.getViewDirection().negative()
plane.alignToPointAndAxis(Vector(0,0,0), viewDirection, self.offset)
self.display(viewDirection)
self.finish()
@ -780,10 +775,10 @@ class Rectangle(Creator):
base = p1
if length < 0:
length = -length
base = base.add(DraftVecUtils.neg(p1.sub(p4)))
base = base.add((p1.sub(p4)).negative())
if height < 0:
height = -height
base = base.add(DraftVecUtils.neg(p1.sub(p2)))
base = base.add((p1.sub(p2)).negative())
self.commit(translate("draft","Create Plane"),
['plane = FreeCAD.ActiveDocument.addObject("Part::Plane","Plane")',
'plane.Length = '+str(length),
@ -915,7 +910,7 @@ class Arc(Creator):
if self.center and DraftVecUtils.dist(self.point,self.center) > 0:
viewdelta = DraftVecUtils.project(self.point.sub(self.center), plane.axis)
if not DraftVecUtils.isNull(viewdelta):
self.point = self.point.add(DraftVecUtils.neg(viewdelta))
self.point = self.point.add(viewdelta.negative())
if (self.step == 0): # choose center
if hasMod(arg,MODALT):
if not self.altdown:
@ -1202,7 +1197,7 @@ class Polygon(Creator):
if self.center and DraftVecUtils.dist(self.point,self.center) > 0:
viewdelta = DraftVecUtils.project(self.point.sub(self.center), plane.axis)
if not DraftVecUtils.isNull(viewdelta):
self.point = self.point.add(DraftVecUtils.neg(viewdelta))
self.point = self.point.add(viewdelta.negative())
if (self.step == 0): # choose center
if hasMod(arg,MODALT):
if not self.altdown:
@ -1356,7 +1351,7 @@ class Ellipse(Creator):
p1 = self.node[0]
p3 = self.node[-1]
diagonal = p3.sub(p1)
halfdiag = DraftVecUtils.scale(diagonal,0.5)
halfdiag = Vector(diagonal).multiply(0.5)
center = p1.add(halfdiag)
p2 = p1.add(DraftVecUtils.project(diagonal, plane.v))
p4 = p1.add(DraftVecUtils.project(diagonal, plane.u))
@ -1452,6 +1447,7 @@ class Text(Creator):
self.ui.sourceCmd = self
self.ui.pointUi(name)
self.call = self.view.addEventCallback("SoEvent",self.action)
self.active = True
self.ui.xValue.setFocus()
self.ui.xValue.selectAll()
msg(translate("draft", "Pick location point:\n"))
@ -1471,7 +1467,7 @@ class Text(Creator):
for l in self.text:
if len(tx) > 1:
tx += ','
tx += '"'+str(l)+'"'
tx += '"'+str(unicode(l).encode("utf8"))+'"'
tx += ']'
self.commit(translate("draft","Create Text"),
['import Draft',
@ -1485,10 +1481,13 @@ class Text(Creator):
if arg["Key"] == "ESCAPE":
self.finish()
elif arg["Type"] == "SoLocation2Event": #mouse movement detection
self.point,ctrlPoint,info = getPoint(self,arg)
if self.active:
self.point,ctrlPoint,info = getPoint(self,arg)
elif arg["Type"] == "SoMouseButtonEvent":
if (arg["State"] == "DOWN") and (arg["Button"] == "BUTTON1"):
if self.point:
self.active = False
FreeCADGui.Snapper.off()
self.node.append(self.point)
self.ui.textUi()
self.ui.textValue.setFocus()
@ -1660,7 +1659,7 @@ class Dimension(Creator):
rad = self.edges[0].Curve.Radius
baseray = self.point.sub(cen)
v2 = DraftVecUtils.scaleTo(baseray,rad)
v1 = DraftVecUtils.neg(v2)
v1 = v2.negative()
if shift:
self.node = [cen,cen.add(v2)]
self.arcmode = "radius"
@ -1701,7 +1700,7 @@ class Dimension(Creator):
if (not self.node) and (not self.support):
self.support = getSupport(arg)
if hasMod(arg,MODALT) and (len(self.node)<3):
print "snapped: ",self.info
#print "snapped: ",self.info
if self.info:
ob = self.doc.getObject(self.info['Object'])
if 'Edge' in self.info['Component']:
@ -1736,7 +1735,7 @@ class Dimension(Creator):
self.node[3],
True,True)
if c:
print "centers:",c
#print "centers:",c
self.center = c[0]
self.arctrack.setCenter(self.center)
self.arctrack.on()
@ -1766,7 +1765,7 @@ class Dimension(Creator):
# for unlinked arc mode:
# if self.arcmode:
# v = self.node[1].sub(self.node[0])
# v = DraftVecUtils.scale(v,0.5)
# v.multiply(0.5)
# cen = self.node[0].add(v)
# self.node = [self.node[0],self.node[1],cen]
self.createObject()
@ -1805,6 +1804,7 @@ class ShapeString(Creator):
self.text = ''
self.ui.sourceCmd = self
self.ui.pointUi(name)
self.active = True
self.call = self.view.addEventCallback("SoEvent",self.action)
self.ui.xValue.setFocus()
self.ui.xValue.selectAll()
@ -1813,7 +1813,7 @@ class ShapeString(Creator):
def createObject(self):
"creates object in the current doc"
# print "debug: D_T ShapeString.createObject type(self.SString): " str(type(self.SString))
#print "debug: D_T ShapeString.createObject type(self.SString): " str(type(self.SString))
# temporary code
#import platform
#if not (platform.system() == 'Linux'):
@ -1842,8 +1842,8 @@ class ShapeString(Creator):
'ss.Support='+sup])
except Exception as e:
msg("Draft_ShapeString: error delaying commit", "error")
print type(e)
print e.args
#print type(e)
#print e.args
self.finish()
def action(self,arg):
@ -1852,11 +1852,14 @@ class ShapeString(Creator):
if arg["Key"] == "ESCAPE":
self.finish()
elif arg["Type"] == "SoLocation2Event": #mouse movement detection
self.point,ctrlPoint,info = getPoint(self,arg)
if self.active:
self.point,ctrlPoint,info = getPoint(self,arg)
elif arg["Type"] == "SoMouseButtonEvent":
if (arg["State"] == "DOWN") and (arg["Button"] == "BUTTON1"):
if self.point:
self.node.append(self.point)
self.active = False
FreeCADGui.Snapper.off()
self.ui.SSUi()
def numericInput(self,numx,numy,numz):
@ -2148,7 +2151,7 @@ class Rotate(Modifier):
if self.center and DraftVecUtils.dist(self.point,self.center):
viewdelta = DraftVecUtils.project(self.point.sub(self.center), plane.axis)
if not DraftVecUtils.isNull(viewdelta):
self.point = self.point.add(DraftVecUtils.neg(viewdelta))
self.point = self.point.add(viewdelta.negative())
if self.extendedCopy:
if not hasMod(arg,MODALT):
self.step = 3
@ -2327,7 +2330,7 @@ class Offset(Modifier):
if dist:
self.ghost.on()
if self.mode == "Wire":
d = DraftVecUtils.neg(dist[0])
d = dist[0].negative()
v1 = DraftGeomUtils.getTangent(self.shape.Edges[0],self.point)
v2 = DraftGeomUtils.getTangent(self.shape.Edges[dist[1]],self.point)
a = -DraftVecUtils.angle(v1,v2)
@ -2335,7 +2338,7 @@ class Offset(Modifier):
occmode = self.ui.occOffset.isChecked()
self.ghost.update(DraftGeomUtils.offsetWire(self.shape,self.dvec,occ=occmode),forceclosed=occmode)
elif self.mode == "BSpline":
d = DraftVecUtils.neg(dist[0])
d = dist[0].negative()
e = self.shape.Edges[0]
basetan = DraftGeomUtils.getTangent(e,self.point)
self.npts = []
@ -2370,7 +2373,7 @@ class Offset(Modifier):
occmode = self.ui.occOffset.isChecked()
if hasMod(arg,MODALT) or self.ui.isCopy.isChecked(): copymode = True
if self.npts:
print "offset:npts=",self.npts
#print "offset:npts=",self.npts
self.commit(translate("draft","Offset"),
['import Draft',
'Draft.offset(FreeCAD.ActiveDocument.'+self.sel.Name+','+DraftVecUtils.toString(self.ntps)+',copy='+str(copymode)+')'])
@ -2661,7 +2664,7 @@ class Trimex(Modifier):
if real:
if self.force:
ray = self.newpoint.sub(v1)
ray = DraftVecUtils.scale(ray,self.force/ray.Length)
ray.multiply(self.force/ray.Length)
self.newpoint = Vector.add(v1,ray)
newedges.append(Part.Line(self.newpoint,v2).toShape())
else:
@ -2673,7 +2676,7 @@ class Trimex(Modifier):
self.ui.labelRadius.setText("Angle")
dist = math.degrees(-ang2)
# if ang1 > ang2: ang1,ang2 = ang2,ang1
print "last calculated:",math.degrees(-ang1),math.degrees(-ang2)
#print "last calculated:",math.degrees(-ang1),math.degrees(-ang2)
ghost.setEndAngle(-ang2)
ghost.setStartAngle(-ang1)
ghost.setCenter(center)
@ -2718,7 +2721,7 @@ class Trimex(Modifier):
"trims the actual object"
if self.extrudeMode:
delta = self.extrude(self.shift,real=True)
print "delta",delta
#print "delta",delta
self.doc.openTransaction("Extrude")
obj = Draft.extrude(self.obj,delta)
self.doc.commitTransaction()
@ -2764,8 +2767,8 @@ class Trimex(Modifier):
self.obj.Z1 = p[0].z
elif Draft.getType(self.obj) == "Circle":
angles = self.ghost[0].getAngles()
print "original",self.obj.FirstAngle," ",self.obj.LastAngle
print "new",angles
#print "original",self.obj.FirstAngle," ",self.obj.LastAngle
#print "new",angles
if angles[0] > angles[1]: angles = (angles[1],angles[0])
self.obj.FirstAngle = angles[0]
self.obj.LastAngle = angles[1]
@ -2870,7 +2873,7 @@ class Scale(Modifier):
# calculate a correction factor depending on the scaling center
corr = Vector(self.node[0].x,self.node[0].y,self.node[0].z)
corr.scale(delta.x,delta.y,delta.z)
corr = DraftVecUtils.neg(corr.sub(self.node[0]))
corr = (corr.sub(self.node[0])).negative()
self.ghost.move(corr)
self.ghost.on()
if self.extendedCopy:
@ -2948,14 +2951,19 @@ class Drawing(Modifier):
'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_Drawing", "Drawing"),
'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_Drawing", "Puts the selected objects on a Drawing sheet.")}
def IsActive(self):
if Draft.getSelection():
return True
else:
return False
def Activated(self):
Modifier.Activated(self,"Drawing")
if not Draft.getSelection():
self.ghost = None
self.ui.selectUi()
msg(translate("draft", "Select an object to project\n"))
self.call = self.view.addEventCallback("SoEvent",selectObject)
else:
self.proceed()
def proceed(self):
if self.call:
self.view.removeEventCallback("SoEvent",self.call)
sel = Draft.getSelection()
if not sel:
self.page = self.createDefaultPage()
@ -3030,19 +3038,25 @@ class Edit(Modifier):
'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_Edit", "Edit"),
'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_Edit", "Edits the active object")}
def IsActive(self):
if Draft.getSelection():
self.selection = Draft.getSelection()
if "Proxy" in self.selection[0].PropertiesList:
if hasattr(self.selection[0].Proxy,"Type"):
return True
return False
def Activated(self):
if self.running:
self.finish()
else:
Modifier.Activated(self,"Edit")
if Draft.getSelection():
self.selection = Draft.getSelection()
if "Proxy" in self.selection[0].PropertiesList:
if hasattr(self.selection[0].Proxy,"Type"):
self.proceed()
return
self.ghost = None
self.ui.selectUi()
msg(translate("draft", "Select a Draft object to edit\n"))
self.call = self.view.addEventCallback("SoEvent",selectObject)
def proceed(self):
if self.call:
self.view.removeEventCallback("SoEvent",self.call)
self.ui.editUi()
if self.doc:
self.obj = Draft.getSelection()
@ -3075,9 +3089,11 @@ class Edit(Modifier):
self.editpoints.append(self.obj.Shape.Vertexes[2].Point)
v = self.obj.Shape.Vertexes
self.bx = v[1].Point.sub(v[0].Point)
if self.obj.Length < 0: self.bx = DraftVecUtils.neg(self.bx)
if self.obj.Length < 0:
self.bx = self.bx.negative()
self.by = v[2].Point.sub(v[1].Point)
if self.obj.Height < 0: self.by = DraftVecUtils.neg(self.by)
if self.obj.Height < 0:
self.by = self.by.negative()
elif Draft.getType(self.obj) == "Polygon":
self.editpoints.append(self.obj.Placement.Base)
self.editpoints.append(self.obj.Shape.Vertexes[0].Point)
@ -3442,8 +3458,6 @@ class WireToBSpline(Modifier):
Draft.formatObject(n,self.selection[0])
else:
self.finish()
def finish(self):
Modifier.finish(self)
class SelectGroup():
@ -3478,20 +3492,27 @@ class SelectGroup():
FreeCADGui.Selection.addSelection(child)
class Shape2DView():
class Shape2DView(Modifier):
"The Shape2DView FreeCAD command definition"
def GetResources(self):
return {'Pixmap' : 'Draft_2DShapeView',
'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_Shape2DView", "Shape 2D view"),
'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_Shape2DView", "Creates Shape 2D views of selected objects")}
def IsActive(self):
if FreeCADGui.Selection.getSelection():
return True
else:
return False
def Activated(self):
Modifier.Activated(self)
if not Draft.getSelection():
if self.ui:
self.ui.selectUi()
msg(translate("draft", "Select an object to project\n"))
self.call = self.view.addEventCallback("SoEvent",selectObject)
else:
self.proceed()
def proceed(self):
if self.call:
self.view.removeEventCallback("SoEvent",self.call)
faces = []
objs = []
sel = FreeCADGui.Selection.getSelectionEx()
@ -3500,28 +3521,37 @@ class Shape2DView():
for e in s.SubElementNames:
if "Face" in e:
faces.append(int(e[4:])-1)
print objs,faces
#print objs,faces
if len(objs) == 1:
if faces:
Draft.makeShape2DView(objs[0],facenumbers=faces)
return
for o in objs:
Draft.makeShape2DView(o)
self.finish()
class Draft2Sketch():
class Draft2Sketch(Modifier):
"The Draft2Sketch FreeCAD command definition"
def GetResources(self):
return {'Pixmap' : 'Draft_Draft2Sketch',
'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_Draft2Sketch", "Draft to Sketch"),
'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_Shape2DView", "Convert bidirectionally between Draft and Sketch objects")}
def IsActive(self):
if Draft.getSelection():
return True
else:
return False
def Activated(self):
Modifier.Activated(self)
if not Draft.getSelection():
if self.ui:
self.ui.selectUi()
msg(translate("draft", "Select an object to convert\n"))
self.call = self.view.addEventCallback("SoEvent",selectObject)
else:
self.proceed()
def proceed(self):
if self.call:
self.view.removeEventCallback("SoEvent",self.call)
sel = Draft.getSelection()
allSketches = True
allDraft = True
@ -3554,26 +3584,37 @@ class Draft2Sketch():
if (len(obj.Shape.Wires) == 1) or (len(obj.Shape.Edges) == 1):
Draft.makeSketch(obj,autoconstraints=False)
FreeCAD.ActiveDocument.commitTransaction()
self.finish()
class Array():
class Array(Modifier):
"The Shape2DView FreeCAD command definition"
def GetResources(self):
return {'Pixmap' : 'Draft_Array',
'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_Array", "Array"),
'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_Array", "Creates a polar or rectangular array from a selected object")}
def IsActive(self):
if len(Draft.getSelection()) == 1:
return True
else:
return False
def Activated(self):
obj = Draft.getSelection()[0]
FreeCAD.ActiveDocument.openTransaction("Array")
Draft.makeArray(obj,Vector(1,0,0),Vector(0,1,0),2,2)
FreeCAD.ActiveDocument.commitTransaction()
Modifier.Activated(self)
if not Draft.getSelection():
if self.ui:
self.ui.selectUi()
msg(translate("draft", "Select an object to array\n"))
self.call = self.view.addEventCallback("SoEvent",selectObject)
else:
self.proceed()
def proceed(self):
if self.call:
self.view.removeEventCallback("SoEvent",self.call)
if Draft.getSelection():
obj = Draft.getSelection()[0]
FreeCAD.ActiveDocument.openTransaction("Array")
Draft.makeArray(obj,Vector(1,0,0),Vector(0,1,0),2,2)
FreeCAD.ActiveDocument.commitTransaction()
self.finish()
class Point:
"this class will create a vertex after the user clicks a point on the screen"
@ -3594,7 +3635,7 @@ class Point:
self.stack = []
rot = self.view.getCameraNode().getField("orientation").getValue()
upv = Vector(rot.multVec(coin.SbVec3f(0,1,0)).getValue())
plane.setup(DraftVecUtils.neg(self.view.getViewDirection()), Vector(0,0,0), upv)
plane.setup(self.view.getViewDirection().negative(), Vector(0,0,0), upv)
self.point = None
# adding 2 callback functions
self.callbackClick = self.view.addEventCallbackPivy(coin.SoMouseButtonEvent.getClassTypeId(),self.click)
@ -3630,19 +3671,6 @@ class Point:
todo.delayCommit(commitlist)
FreeCADGui.Snapper.off()
class ToggleSnap():
"The ToggleSnap FreeCAD command definition"
def GetResources(self):
return {'Pixmap' : 'Snap_Lock',
'Accel' : "Shift+S",
'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_ToggleSnap", "Toggle snap"),
'ToolTip' : QtCore.QT_TRANSLATE_NOOP("Draft_ToggleSnap", "Toggles Draft snap on or off")}
def Activated(self):
if hasattr(FreeCADGui,"Snapper"):
FreeCADGui.Snapper.toggle()
class ShowSnapBar():
"The ShowSnapBar FreeCAD command definition"
@ -3655,7 +3683,7 @@ class ShowSnapBar():
FreeCADGui.Snapper.show()
class Draft_Clone():
class Draft_Clone(Modifier):
"The Draft Clone command definition"
def GetResources(self):
@ -3665,17 +3693,24 @@ class Draft_Clone():
'ToolTip' : QtCore.QT_TRANSLATE_NOOP("Draft_Clone", "Clones the selected object(s)")}
def Activated(self):
Modifier.Activated(self)
if not Draft.getSelection():
if self.ui:
self.ui.selectUi()
msg(translate("draft", "Select an object to clone\n"))
self.call = self.view.addEventCallback("SoEvent",selectObject)
else:
self.proceed()
def proceed(self):
if self.call:
self.view.removeEventCallback("SoEvent",self.call)
if FreeCADGui.Selection.getSelection():
FreeCAD.ActiveDocument.openTransaction("Clone")
for obj in FreeCADGui.Selection.getSelection():
Draft.clone(obj)
FreeCAD.ActiveDocument.commitTransaction()
def IsActive(self):
if FreeCADGui.Selection.getSelection():
return True
else:
return False
self.finish()
class ToggleGrid():
@ -3723,12 +3758,12 @@ class Heal():
class Draft_Snap_Lock():
def GetResources(self):
return {'Pixmap' : 'Snap_Lock',
'Accel' : "Shift+S",
'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_Snap_Lock", "Toggle On/Off"),
'ToolTip' : QtCore.QT_TRANSLATE_NOOP("Draft_Snap_Lock", "Activates/deactivates all snap tools at once")}
def Activated(self):
if hasattr(FreeCADGui,"Snapper"):
if hasattr(FreeCADGui.Snapper,"masterbutton"):
print FreeCADGui.Snapper.masterbutton
FreeCADGui.Snapper.masterbutton.toggle()
class Draft_Snap_Midpoint():
@ -3911,7 +3946,6 @@ FreeCADGui.addCommand('Draft_ToggleDisplayMode',ToggleDisplayMode())
FreeCADGui.addCommand('Draft_AddToGroup',AddToGroup())
FreeCADGui.addCommand('Draft_SelectGroup',SelectGroup())
FreeCADGui.addCommand('Draft_Shape2DView',Shape2DView())
FreeCADGui.addCommand('Draft_ToggleSnap',ToggleSnap())
FreeCADGui.addCommand('Draft_ShowSnapBar',ShowSnapBar())
FreeCADGui.addCommand('Draft_ToggleGrid',ToggleGrid())

View File

@ -272,8 +272,8 @@ class dimTracker(Tracker):
p2 = p1
p3 = p4
else:
p2 = p1.add(DraftVecUtils.neg(proj))
p3 = p4.add(DraftVecUtils.neg(proj))
p2 = p1.add(proj.negative())
p3 = p4.add(proj.negative())
points = [DraftVecUtils.tup(p1),DraftVecUtils.tup(p2),DraftVecUtils.tup(p3),DraftVecUtils.tup(p4)]
self.coords.point.setValues(0,4,points)
@ -743,7 +743,7 @@ class boxTracker(Tracker):
self.cube.width.setValue(lvec.Length)
p = WorkingPlane.getPlacementFromPoints([bp,bp.add(lvec),bp.add(right)])
self.trans.rotation.setValue(p.Rotation.Q)
bp = bp.add(DraftVecUtils.scale(lvec,0.5))
bp = bp.add(lvec.multiply(0.5))
bp = bp.add(DraftVecUtils.scaleTo(normal,self.cube.depth.getValue()/2))
self.pos(bp)

File diff suppressed because it is too large Load Diff

View File

@ -112,11 +112,12 @@ class DraftWorkbench (Workbench):
"Draft_Trimex", "Draft_Upgrade", "Draft_Downgrade", "Draft_Scale",
"Draft_Drawing","Draft_Edit","Draft_WireToBSpline","Draft_AddPoint",
"Draft_DelPoint","Draft_Shape2DView","Draft_Draft2Sketch","Draft_Array",
"Draft_Clone","Draft_Heal"]
"Draft_Clone"]
self.treecmdList = ["Draft_ApplyStyle","Draft_ToggleDisplayMode","Draft_AddToGroup",
"Draft_SelectGroup","Draft_SelectPlane","Draft_ToggleSnap",
"Draft_SelectGroup","Draft_SelectPlane",
"Draft_ShowSnapBar","Draft_ToggleGrid"]
self.lineList = ["Draft_UndoLine","Draft_FinishLine","Draft_CloseLine"]
self.utils = ["Draft_Heal"]
self.snapList = ['Draft_Snap_Lock','Draft_Snap_Midpoint','Draft_Snap_Perpendicular',
'Draft_Snap_Grid','Draft_Snap_Intersection','Draft_Snap_Parallel',
'Draft_Snap_Endpoint','Draft_Snap_Angle','Draft_Snap_Center',
@ -125,11 +126,13 @@ class DraftWorkbench (Workbench):
self.appendToolbar(QT_TRANSLATE_NOOP("Workbench","Draft modification tools"),self.modList)
self.appendMenu(str(translate("draft","&Draft")),self.cmdList+self.modList)
self.appendMenu([str(translate("draft","&Draft")),str(translate("draft","Context tools"))],self.treecmdList)
self.appendMenu([str(translate("draft","&Draft")),str(translate("draft","Utilities"))],self.utils)
self.appendMenu([str(translate("draft","&Draft")),str(translate("draft","Wire tools"))],self.lineList)
self.appendMenu([str(translate("draft","&Draft")),str(translate("draft","Snapping"))],self.snapList)
if hasattr(FreeCADGui,"draftToolBar"):
if not hasattr(FreeCADGui.draftToolBar,"loadedPreferences"):
FreeCADGui.addPreferencePage(":/ui/userprefs-base.ui","Draft")
FreeCADGui.addPreferencePage(":/ui/userprefs-visual.ui","Draft")
FreeCADGui.addPreferencePage(":/ui/userprefs-import.ui","Draft")
FreeCADGui.draftToolBar.loadedPreferences = True
Log ('Loading Draft module...done\n')
@ -178,13 +181,5 @@ App.addImportType("Common airfoil data (*.dat)","importAirfoilDAT")
App.addExportType("Autodesk DXF (*.dxf)","importDXF")
App.addExportType("Flattened SVG (*.svg)","importSVG")
App.addExportType("Open CAD Format (*.oca)","importOCA")
# add DWG support
import importDWG
if importDWG.getTeighaConverter():
App.addImportType("Autodesk DWG (*.dwg)","importDWG")
App.addExportType("Autodesk DWG (*.dwg)","importDWG")
else:
from DraftTools import translate
FreeCAD.Console.PrintMessage(str(translate("draft","Teigha File Converter not found, DWG support will be disabled.\n")))
App.addImportType("Autodesk DWG (*.dwg)","importDWG")
App.addExportType("Autodesk DWG (*.dwg)","importDWG")

View File

@ -86,5 +86,6 @@
<file>translations/Draft_pt-PT.qm</file>
<file>ui/userprefs-base.ui</file>
<file>ui/userprefs-import.ui</file>
<file>ui/userprefs-visual.ui</file>
</qresource>
</RCC>

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>575</width>
<height>629</height>
<height>666</height>
</rect>
</property>
<property name="windowTitle">
@ -97,6 +97,78 @@ If color mapping is choosed, you must choose a color mapping file containing a t
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_7">
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Import</string>
</property>
</widget>
</item>
<item>
<widget class="Gui::PrefCheckBox" name="gui::prefcheckbox_2">
<property name="toolTip">
<string>if this is unchecked, texts/mtexts won't be imported</string>
</property>
<property name="text">
<string>texts and dimensions</string>
</property>
<property name="prefEntry" stdset="0">
<cstring>dxftext</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Draft</cstring>
</property>
</widget>
</item>
<item>
<widget class="Gui::PrefCheckBox" name="gui::prefcheckbox_13">
<property name="text">
<string>points</string>
</property>
<property name="prefEntry" stdset="0">
<cstring>dxfImportPoints</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Draft</cstring>
</property>
</widget>
</item>
<item>
<widget class="Gui::PrefCheckBox" name="gui::prefcheckbox_3">
<property name="toolTip">
<string>if this is checked, paper space objects will be imported too</string>
</property>
<property name="text">
<string>layouts</string>
</property>
<property name="prefEntry" stdset="0">
<cstring>dxflayout</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Draft</cstring>
</property>
</widget>
</item>
<item>
<widget class="Gui::PrefCheckBox" name="gui::prefcheckbox_7">
<property name="toolTip">
<string>Check this if you want the non-named blocks (beginning with a *) to be imported too</string>
</property>
<property name="text">
<string>*blocks</string>
</property>
<property name="prefEntry" stdset="0">
<cstring>dxfstarblocks</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Draft</cstring>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
@ -160,66 +232,6 @@ If color mapping is choosed, you must choose a color mapping file containing a t
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_7">
<item>
<widget class="Gui::PrefCheckBox" name="gui::prefcheckbox_2">
<property name="toolTip">
<string>if this is unchecked, texts/mtexts won't be imported</string>
</property>
<property name="text">
<string>Import texts and dimensions</string>
</property>
<property name="prefEntry" stdset="0">
<cstring>dxftext</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Draft</cstring>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="Gui::PrefCheckBox" name="gui::prefcheckbox_3">
<property name="toolTip">
<string>if this is checked, paper space objects will be imported too</string>
</property>
<property name="text">
<string>Import layouts</string>
</property>
<property name="prefEntry" stdset="0">
<cstring>dxflayout</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Draft</cstring>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="Gui::PrefCheckBox" name="gui::prefcheckbox_7">
<property name="toolTip">
<string>Check this if you want the non-named blocks (beginning with a *) to be imported too</string>
</property>
<property name="text">
<string>Import *blocks</string>
</property>
<property name="prefEntry" stdset="0">
<cstring>dxfstarblocks</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Draft</cstring>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_8">
<item>
@ -363,6 +375,39 @@ If color mapping is choosed, you must choose a color mapping file containing a t
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>DWG format options</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>Path to Teigha File Converter</string>
</property>
</widget>
</item>
<item>
<widget class="Gui::PrefFileChooser" name="gui::preffilechooser_2">
<property name="toolTip">
<string>The path to your Teigha File Converter executable</string>
</property>
<property name="prefEntry" stdset="0">
<cstring>TeighaFileConverter</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Draft</cstring>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="GroupBox12_2">
<property name="title">

View File

@ -0,0 +1,905 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Gui::Dialog::DlgSettingsDraft</class>
<widget class="QWidget" name="Gui::Dialog::DlgSettingsDraft">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>718</width>
<height>808</height>
</rect>
</property>
<property name="windowTitle">
<string>Visual settings</string>
</property>
<layout class="QVBoxLayout">
<property name="spacing">
<number>6</number>
</property>
<property name="margin">
<number>9</number>
</property>
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Visual Settings</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Default line color</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="Gui::PrefColorButton" name="gui::prefcolorbutton">
<property name="toolTip">
<string>the default color for new objects</string>
</property>
<property name="color">
<color>
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</property>
<property name="prefEntry" stdset="0">
<cstring>color</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Draft</cstring>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_7">
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Default line width</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="Gui::PrefSpinBox" name="gui::prefspinbox">
<property name="toolTip">
<string>the default linewidth for new objects</string>
</property>
<property name="value">
<number>2</number>
</property>
<property name="prefEntry" stdset="0">
<cstring>linewidth</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Draft</cstring>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>Snap symbols color</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="Gui::PrefColorButton" name="gui::prefcolorbutton_2">
<property name="toolTip">
<string>the default color for snap symbols</string>
</property>
<property name="color">
<color>
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</property>
<property name="prefEntry" stdset="0">
<cstring>snapcolor</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Draft</cstring>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="Gui::PrefCheckBox" name="gui::prefcheckbox">
<property name="toolTip">
<string>check this if you want to use the color/linewidth from the toolbar as default</string>
</property>
<property name="text">
<string>Save current color and linewidth across sessions</string>
</property>
<property name="prefEntry" stdset="0">
<cstring>saveonexit</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Draft</cstring>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_12">
<item>
<widget class="Gui::PrefCheckBox" name="gui::prefcheckbox_11">
<property name="toolTip">
<string>if checked, a widget indicating the current working plane orientation appears during drawing operations</string>
</property>
<property name="text">
<string>Show Working Plane tracker</string>
</property>
<property name="prefEntry" stdset="0">
<cstring>showPlaneTracker</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Draft</cstring>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_8">
<item>
<widget class="Gui::PrefCheckBox" name="gui::prefcheckbox_6">
<property name="toolTip">
<string>If this is checked, objects will appear as filled as default. Otherwise, they will appear as wireframe</string>
</property>
<property name="text">
<string>Fill objects by default</string>
</property>
<property name="prefEntry" stdset="0">
<cstring>fillmode</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Draft</cstring>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_11">
<item>
<widget class="QLabel" name="label_11">
<property name="text">
<string>Default template sheet</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_11">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="Gui::PrefFileChooser" name="gui::preffilechooser_2">
<property name="minimumSize">
<size>
<width>300</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>The default template to use when creating a new drawing sheet</string>
</property>
<property name="prefEntry" stdset="0">
<cstring>template</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Draft</cstring>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label_13">
<property name="text">
<string>Alternate SVG Patterns location</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_10">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="Gui::PrefFileChooser" name="gui::preffilechooser_3">
<property name="minimumSize">
<size>
<width>300</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>Here you can specify a directory containing SVG files containing &lt;pattern&gt; definitions that can be added to the standard Draft hatch patterns</string>
</property>
<property name="prefEntry" stdset="0">
<cstring>patternFile</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Draft</cstring>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_18">
<item>
<widget class="QLabel" name="label_7">
<property name="text">
<string>Hatch patterns resolution</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_12">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="Gui::PrefSpinBox" name="gui::prefspinbox_2">
<property name="maximum">
<number>512</number>
</property>
<property name="value">
<number>128</number>
</property>
<property name="prefEntry" stdset="0">
<cstring>HatchPatternResolution</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Draft</cstring>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_3">
<property name="title">
<string>Grid</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_17">
<item>
<widget class="Gui::PrefCheckBox" name="gui::prefcheckbox_2">
<property name="toolTip">
<string>If checked, a grid will appear when drawing</string>
</property>
<property name="text">
<string>Use grid</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
<property name="prefEntry" stdset="0">
<cstring>grid</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Draft</cstring>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_15">
<item>
<widget class="Gui::PrefCheckBox" name="gui::prefcheckbox_10">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>If checked, the Draft grid will always be visible when the Draft workbench is active. Otherwise only when using a command</string>
</property>
<property name="text">
<string>Always show the grid</string>
</property>
<property name="prefEntry" stdset="0">
<cstring>alwaysShowGrid</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Draft</cstring>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_10">
<item>
<widget class="QLabel" name="label_15">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Grid spacing</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_7">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="Gui::PrefDoubleSpinBox" name="gui::prefdoublespinbox_3">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>The spacing between each grid line</string>
</property>
<property name="decimals">
<number>4</number>
</property>
<property name="maximum">
<double>9999.989999999999782</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
<property name="prefEntry" stdset="0">
<cstring>gridSpacing</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Draft</cstring>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_13">
<item>
<widget class="QLabel" name="label_16">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Main lines every</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_8">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="Gui::PrefSpinBox" name="gui::prefspinbox_4">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>Mainlines will be drawn thicker. Specify here how many squares between mainlines.</string>
</property>
<property name="value">
<number>10</number>
</property>
<property name="prefEntry" stdset="0">
<cstring>gridEvery</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Draft</cstring>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>Texts and dimensions</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_6">
<item>
<widget class="QLabel" name="label_6">
<property name="text">
<string>Default text height</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_6">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="Gui::PrefDoubleSpinBox" name="gui::prefdoublespinbox_2">
<property name="maximumSize">
<size>
<width>60</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Default height for texts and dimensions</string>
</property>
<property name="value">
<double>0.200000000000000</double>
</property>
<property name="prefEntry" stdset="0">
<cstring>textheight</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Draft</cstring>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_9">
<item>
<widget class="QLabel" name="label_5">
<property name="text">
<string>Default text font</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="Gui::PrefLineEdit" name="gui::preflineedit">
<property name="toolTip">
<string>This is the default font name for all Draft texts and dimensions.
It can be a font name such as &quot;Arial&quot;, a default style such as &quot;sans&quot;, &quot;serif&quot;
or &quot;mono&quot;, or a family such as &quot;Arial,Helvetica,sans&quot; or a name with a style
such as &quot;Arial:Bold&quot;</string>
</property>
<property name="text">
<string>Arial</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="prefEntry" stdset="0">
<cstring>textfont</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Draft</cstring>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_14">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Dimensions &amp; Leader arrow style</string>
</property>
</widget>
</item>
<item>
<widget class="Gui::PrefComboBox" name="gui::prefcombobox">
<property name="prefEntry" stdset="0">
<cstring>dimsymbol</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Draft</cstring>
</property>
<item>
<property name="text">
<string>Dot 5</string>
</property>
</item>
<item>
<property name="text">
<string>Dot 7</string>
</property>
</item>
<item>
<property name="text">
<string>Dot 9</string>
</property>
</item>
<item>
<property name="text">
<string>Circle 5</string>
</property>
</item>
<item>
<property name="text">
<string>Circle 7</string>
</property>
</item>
<item>
<property name="text">
<string>Circle 9</string>
</property>
</item>
<item>
<property name="text">
<string>Slash 5</string>
</property>
</item>
<item>
<property name="text">
<string>Slash 7</string>
</property>
</item>
<item>
<property name="text">
<string>Slash 9</string>
</property>
</item>
<item>
<property name="text">
<string>Backslash 5</string>
</property>
</item>
<item>
<property name="text">
<string>Backslash 7</string>
</property>
</item>
<item>
<property name="text">
<string>Backslash 9</string>
</property>
</item>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_16">
<item>
<widget class="QLabel" name="label_14">
<property name="text">
<string>Vertical dimensions text orientation</string>
</property>
</widget>
</item>
<item>
<widget class="Gui::PrefComboBox" name="gui::prefcombobox_3">
<property name="toolTip">
<string>This is the orientation of the dimension texts when those dimensions are vertical. Default is left, which is the ISO standard.</string>
</property>
<property name="prefEntry" stdset="0">
<cstring>dimorientation</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Draft</cstring>
</property>
<item>
<property name="text">
<string>Left (ISO standard)</string>
</property>
</item>
<item>
<property name="text">
<string>Right</string>
</property>
</item>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_23">
<item>
<widget class="QLabel" name="label_24">
<property name="text">
<string>Default ShapeString Font File</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_9">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="Gui::PrefFileChooser" name="gui::preffilechooser">
<property name="minimumSize">
<size>
<width>300</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>Select a font file</string>
</property>
<property name="prefEntry" stdset="0">
<cstring>FontFile</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Draft</cstring>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<layoutdefault spacing="6" margin="11"/>
<pixmapfunction>qPixmapFromMimeSource</pixmapfunction>
<customwidgets>
<customwidget>
<class>Gui::FileChooser</class>
<extends>QWidget</extends>
<header>Gui/FileDialog.h</header>
</customwidget>
<customwidget>
<class>Gui::ColorButton</class>
<extends>QPushButton</extends>
<header>Gui/Widgets.h</header>
</customwidget>
<customwidget>
<class>Gui::PrefFileChooser</class>
<extends>Gui::FileChooser</extends>
<header>Gui/PrefWidgets.h</header>
</customwidget>
<customwidget>
<class>Gui::PrefSpinBox</class>
<extends>QSpinBox</extends>
<header>Gui/PrefWidgets.h</header>
</customwidget>
<customwidget>
<class>Gui::PrefColorButton</class>
<extends>Gui::ColorButton</extends>
<header>Gui/PrefWidgets.h</header>
</customwidget>
<customwidget>
<class>Gui::PrefCheckBox</class>
<extends>QCheckBox</extends>
<header>Gui/PrefWidgets.h</header>
</customwidget>
<customwidget>
<class>Gui::PrefComboBox</class>
<extends>QComboBox</extends>
<header>Gui/PrefWidgets.h</header>
</customwidget>
<customwidget>
<class>Gui::PrefLineEdit</class>
<extends>QLineEdit</extends>
<header>Gui/PrefWidgets.h</header>
</customwidget>
<customwidget>
<class>Gui::PrefDoubleSpinBox</class>
<extends>QDoubleSpinBox</extends>
<header>Gui/PrefWidgets.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections>
<connection>
<sender>gui::prefcheckbox_2</sender>
<signal>clicked(bool)</signal>
<receiver>gui::prefdoublespinbox_3</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>92</x>
<y>379</y>
</hint>
<hint type="destinationlabel">
<x>417</x>
<y>381</y>
</hint>
</hints>
</connection>
<connection>
<sender>gui::prefcheckbox_2</sender>
<signal>clicked(bool)</signal>
<receiver>gui::prefspinbox_4</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>79</x>
<y>373</y>
</hint>
<hint type="destinationlabel">
<x>571</x>
<y>374</y>
</hint>
</hints>
</connection>
<connection>
<sender>gui::prefcheckbox_2</sender>
<signal>clicked(bool)</signal>
<receiver>label_15</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>58</x>
<y>365</y>
</hint>
<hint type="destinationlabel">
<x>354</x>
<y>381</y>
</hint>
</hints>
</connection>
<connection>
<sender>gui::prefcheckbox_2</sender>
<signal>clicked(bool)</signal>
<receiver>label_16</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>33</x>
<y>367</y>
</hint>
<hint type="destinationlabel">
<x>516</x>
<y>381</y>
</hint>
</hints>
</connection>
<connection>
<sender>gui::prefcheckbox_2</sender>
<signal>clicked(bool)</signal>
<receiver>gui::prefcheckbox_10</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>72</x>
<y>375</y>
</hint>
<hint type="destinationlabel">
<x>226</x>
<y>373</y>
</hint>
</hints>
</connection>
</connections>
</ui>

142
src/Mod/Draft/TestDraft.py Normal file
View File

@ -0,0 +1,142 @@
# Unit test for the Draft module
#***************************************************************************
#* (c) Yorik van Havre <yorik@uncreated.net> 2013 *
#* *
#* 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 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 *
#* *
#***************************************************************************/
import FreeCAD, os, unittest, FreeCADGui, Draft
class DraftTest(unittest.TestCase):
def setUp(self):
# setting a new document to hold the tests
if FreeCAD.ActiveDocument:
if FreeCAD.ActiveDocument.Name != "DraftTest":
FreeCAD.newDocument("DraftTest")
else:
FreeCAD.newDocument("DraftTest")
FreeCAD.setActiveDocument("DraftTest")
def testPivy(self):
FreeCAD.Console.PrintLog ('Checking Pivy...\n')
from pivy import coin
c = coin.SoCube()
FreeCADGui.ActiveDocument.ActiveView.getSceneGraph().addChild(c)
self.failUnless(c,"Pivy is not working properly")
# creation tools
def testLine(self):
FreeCAD.Console.PrintLog ('Checking Draft Line...\n')
Draft.makeLine(FreeCAD.Vector(0,0,0),FreeCAD.Vector(-2,0,0))
self.failUnless(FreeCAD.ActiveDocument.getObject("Line"),"Draft Line failed")
def testWire(self):
FreeCAD.Console.PrintLog ('Checking Draft Wire...\n')
Draft.makeWire([FreeCAD.Vector(0,0,0),FreeCAD.Vector(2,0,0),FreeCAD.Vector(2,2,0)])
self.failUnless(FreeCAD.ActiveDocument.getObject("DWire"),"Draft Wire failed")
def testBSpline(self):
FreeCAD.Console.PrintLog ('Checking Draft BSpline...\n')
Draft.makeBSpline([FreeCAD.Vector(0,0,0),FreeCAD.Vector(2,0,0),FreeCAD.Vector(2,2,0)])
self.failUnless(FreeCAD.ActiveDocument.getObject("BSpline"),"Draft BSpline failed")
def testRectangle(self):
FreeCAD.Console.PrintLog ('Checking Draft Rectangle...\n')
Draft.makeRectangle(4,2)
self.failUnless(FreeCAD.ActiveDocument.getObject("Rectangle"),"Draft Rectangle failed")
def testArc(self):
FreeCAD.Console.PrintLog ('Checking Draft Arc...\n')
Draft.makeCircle(2, startangle=0, endangle=90)
self.failUnless(FreeCAD.ActiveDocument.getObject("Arc"),"Draft Arc failed")
def testCircle(self):
FreeCAD.Console.PrintLog ('Checking Draft Circle...\n')
Draft.makeCircle(3)
self.failUnless(FreeCAD.ActiveDocument.getObject("Circle"),"Draft Circle failed")
def testPolygon(self):
FreeCAD.Console.PrintLog ('Checking Draft Polygon...\n')
Draft.makePolygon(5,5)
self.failUnless(FreeCAD.ActiveDocument.getObject("Polygon"),"Draft Polygon failed")
def testEllipse(self):
FreeCAD.Console.PrintLog ('Checking Draft Ellipse...\n')
Draft.makeEllipse(5,3)
self.failUnless(FreeCAD.ActiveDocument.getObject("Ellipse"),"Draft Ellipse failed")
def testPoint(self):
FreeCAD.Console.PrintLog ('Checking Draft Point...\n')
Draft.makePoint(5,3,2)
self.failUnless(FreeCAD.ActiveDocument.getObject("Point"),"Draft Point failed")
def testText(self):
FreeCAD.Console.PrintLog ('Checking Draft Text...\n')
Draft.makeText("Testing Draft")
self.failUnless(FreeCAD.ActiveDocument.getObject("Text"),"Draft Text failed")
#def testShapeString(self):
# not working ATM because it needs a font file
# FreeCAD.Console.PrintLog ('Checking Draft ShapeString...\n')
# Draft.makeShapeString("Testing Draft")
# self.failUnless(FreeCAD.ActiveDocument.getObject("ShapeString"),"Draft ShapeString failed")
def testDimension(self):
FreeCAD.Console.PrintLog ('Checking Draft Dimension...\n')
Draft.makeDimension(FreeCAD.Vector(0,0,0),FreeCAD.Vector(2,0,0),FreeCAD.Vector(1,-1,0))
self.failUnless(FreeCAD.ActiveDocument.getObject("Dimension"),"Draft Dimension failed")
# modification tools
def testMove(self):
FreeCAD.Console.PrintLog ('Checking Draft Move...\n')
l = Draft.makeLine(FreeCAD.Vector(0,0,0),FreeCAD.Vector(-2,0,0))
Draft.move(l,FreeCAD.Vector(2,0,0))
self.failUnless(l.Start == FreeCAD.Vector(2,0,0),"Draft Move failed")
def testCopy(self):
FreeCAD.Console.PrintLog ('Checking Draft Move with copy...\n')
l = Draft.makeLine(FreeCAD.Vector(0,0,0),FreeCAD.Vector(2,0,0))
l2 = Draft.move(l,FreeCAD.Vector(2,0,0),copy=True)
self.failUnless(l2,"Draft Move with copy failed")
def testRotate(self):
FreeCAD.Console.PrintLog ('Checking Draft Rotate...\n')
l = Draft.makeLine(FreeCAD.Vector(2,0,0),FreeCAD.Vector(4,0,0))
Draft.rotate(l,90)
self.failUnless(l.Start == FreeCAD.Vector(0,2,0),"Draft Rotate failed")
def testOffset(self):
FreeCAD.Console.PrintLog ('Checking Draft Offset...\n')
r = Draft.makeRectangle(4,2)
r2 = Draft.offset(r,FreeCAD.Vector(-1,-1,0),copy=True)
self.failUnless(r2,"Draft Offset failed")
# modification tools
def tearDown(self):
FreeCAD.closeDocument("DraftTest")
pass

View File

@ -92,7 +92,7 @@ class plane:
gp = self.getGlobalCoords(Vector(lp.x,lp.y,0))
a = direction.getAngle(gp.sub(p))
if a > math.pi/2:
direction = DraftVecUtils.neg(direction)
direction = direction.negative()
a = math.pi - a
ld = self.getLocalRot(direction)
gd = self.getGlobalRot(Vector(ld.x,ld.y,0))
@ -158,7 +158,7 @@ class plane:
v1.normalize()
v2.normalize()
v3.normalize()
print v1,v2,v3
#print v1,v2,v3
self.u = v1
self.v = v2
self.axis = v3
@ -187,10 +187,20 @@ class plane:
# len(sex) > 2, look for point and line, three points, etc.
return False
def setup(self, direction, point, upvec=None):
def setup(self, direction=None, point=None, upvec=None):
'''If working plane is undefined, define it!'''
if self.weak:
self.alignToPointAndAxis(point, direction, 0, upvec)
if direction and point:
self.alignToPointAndAxis(point, direction, 0, upvec)
else:
try:
from pivy import coin
rot = FreeCADGui.ActiveDocument.ActiveView.getCameraNode().getField("orientation").getValue()
upvec = Vector(rot.multVec(coin.SbVec3f(0,1,0)).getValue())
vdir = FreeCADGui.ActiveDocument.ActiveView.getViewDirection()
self.alignToPointAndAxis(Vector(0,0,0), vdir.negative(), 0, upvec)
except:
print "Draft: Unable to align the working plane to the current view"
self.weak = True
def reset(self):
@ -251,9 +261,9 @@ class plane:
def getGlobalCoords(self,point):
"returns the global coordinates of the given point, taken relatively to this working plane"
vx = DraftVecUtils.scale(self.u,point.x)
vy = DraftVecUtils.scale(self.v,point.y)
vz = DraftVecUtils.scale(self.axis,point.z)
vx = Vector(self.u).multiply(point.x)
vy = Vector(self.v).multiply(point.y)
vz = Vector(self.axis).multiply(point.z)
pt = (vx.add(vy)).add(vz)
return pt.add(self.position)
@ -275,9 +285,9 @@ class plane:
def getGlobalRot(self,point):
"Same as getGlobalCoords, but discards the WP position"
vx = DraftVecUtils.scale(self.u,point.x)
vy = DraftVecUtils.scale(self.v,point.y)
vz = DraftVecUtils.scale(self.axis,point.z)
vx = Vector(self.u).multiply(point.x)
vy = Vector(self.v).multiply(point.y)
vz = Vector(self.axis).multiply(point.z)
pt = (vx.add(vy)).add(vz)
return pt
@ -286,9 +296,9 @@ class plane:
ax = point.getAngle(self.u)
ay = point.getAngle(self.v)
az = point.getAngle(self.axis)
bx = point.getAngle(DraftVecUtils.neg(self.u))
by = point.getAngle(DraftVecUtils.neg(self.v))
bz = point.getAngle(DraftVecUtils.neg(self.axis))
bx = point.getAngle(self.u.negative())
by = point.getAngle(self.v.negative())
bz = point.getAngle(self.axis.negative())
b = min(ax,ay,az,bx,by,bz)
if b in [ax,bx]:
return "x"

View File

@ -30,16 +30,20 @@ if open.__module__ == '__builtin__':
def open(filename):
"called when freecad opens a file."
dxf = convertToDxf(filename)
import importDXF
doc = importDXF.open(dxf)
return doc
if dxf:
import importDXF
doc = importDXF.open(dxf)
return doc
return
def insert(filename,docname):
"called when freecad imports a file"
dxf = convertToDxf(filemname)
import importDXF
doc = importDXF.insert(dxf,docname)
return doc
if dxf:
import importDXF
doc = importDXF.insert(dxf,docname)
return doc
return
def export(objectslist,filename):
"called when freecad exports a file"
@ -51,44 +55,64 @@ def export(objectslist,filename):
return filename
def getTeighaConverter():
import FreeCAD,os,platform
"finds the Teigha Converter executable"
import os,platform
teigha = None
if platform.system() == "Linux":
teigha = "/usr/bin/TeighaFileConverter"
elif platform.system() == "Windows":
odadir = "C:\Program Files\ODA"
if os.path.exists(odadir):
subdirs = os.walk(odadir).next()[1]
for sub in subdirs:
t = odadir + os.sep + sub + os.sep + "TeighaFileConverter.exe"
if os.path.exists(t):
teigha = t
p = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Draft")
p = p.GetString("TeighaFileConverter")
if p:
# path set manually
teigha = p
else:
# try to find teigha
teigha = None
if platform.system() == "Linux":
teigha = "/usr/bin/TeighaFileConverter"
elif platform.system() == "Windows":
odadir = "C:\Program Files\ODA"
if os.path.exists(odadir):
subdirs = os.walk(odadir).next()[1]
for sub in subdirs:
t = odadir + os.sep + sub + os.sep + "TeighaFileConverter.exe"
if os.path.exists(t):
teigha = t
if teigha:
if os.path.exists(teigha):
return teigha
from DraftTools import translate
FreeCAD.Console.PrintMessage(str(translate("draft","Teigha File Converter not found, DWG support is disabled.\n")))
return None
def convertToDxf(dwgfilename):
"converts a DWG file to DXF"
import os,tempfile
teigha = getTeighaConverter()
indir = os.path.dirname(dwgfilename)
outdir = tempfile.mkdtemp()
basename = os.path.basename(dwgfilename)
cmdline = teigha + ' "' + indir + '" "' + outdir + '" "ACAD2010" "DXF" "0" "1" "' + basename + '"'
print "converting " + cmdline
os.system(cmdline)
return outdir + os.sep + os.path.splitext(basename)[0] + ".dxf"
if teigha:
indir = os.path.dirname(dwgfilename)
outdir = tempfile.mkdtemp()
basename = os.path.basename(dwgfilename)
cmdline = teigha + ' "' + indir + '" "' + outdir + '" "ACAD2010" "DXF" "0" "1" "' + basename + '"'
print "Converting: " + cmdline
os.system(cmdline)
result = outdir + os.sep + os.path.splitext(basename)[0] + ".dxf"
if os.path.exists(result):
print "Conversion successful"
return result
else:
print "Error during DWG to DXF conversion. Try moving the DWG file to a directory path"
print "without spaces and non-english characters, or try saving to a lower DWG version"
return None
def convertToDwg(dxffilename,dwgfilename):
"converts a DXF file to DWG"
import os
teigha = getTeighaConverter()
indir = os.path.dirname(dxffilename)
outdir = os.path.dirname(dwgfilename)
basename = os.path.basename(dxffilename)
cmdline = teigha + ' "' + indir + '" "' + outdir + '" "ACAD2010" "DWG" "0" "1" "' + basename + '"'
print "converting " + cmdline
os.system(cmdline)
return dwgfilename
if teigha:
indir = os.path.dirname(dxffilename)
outdir = os.path.dirname(dwgfilename)
basename = os.path.basename(dxffilename)
cmdline = teigha + ' "' + indir + '" "' + outdir + '" "ACAD2010" "DWG" "0" "1" "' + basename + '"'
print "converting " + cmdline
os.system(cmdline)
return dwgfilename
return None

View File

@ -39,6 +39,8 @@ lines, polylines, lwpolylines, circles, arcs,
texts, colors,layers (from groups)
'''
TEXTSCALING = 1.35 # scaling factor between autocad font sizes and coin font sizes
import sys, FreeCAD, os, Part, math, re, string, Mesh, Draft, DraftVecUtils, DraftGeomUtils
from Draft import _Dimension, _ViewProviderDimension
from FreeCAD import Vector
@ -86,34 +88,24 @@ def deformat(text):
"removes weird formats in texts and wipes UTF characters"
# remove ACAD string formatation
#t = re.sub('{([^!}]([^}]|\n)*)}', '', text)
print "input text: ",text
t = text.strip("{}")
t = re.sub("\\\.*?;","",t)
# replace UTF codes
t = re.sub("\\\\U\+00e9","e",t)
t = re.sub("\\\\U\+00e1","a",t)
t = re.sub("\\\\U\+00e7","c",t)
t = re.sub("\\\\U\+00e3","a",t)
t = re.sub("\\\\U\+00e0","a",t)
t = re.sub("\\\\U\+00c1","A",t)
t = re.sub("\\\\U\+00ea","e",t)
# replace non-UTF chars
t = re.sub("ã","a",t)
t = re.sub("ç","c",t)
t = re.sub("õ","o",t)
t = re.sub("à","a",t)
t = re.sub("á","a",t)
t = re.sub("â","a",t)
t = re.sub("é","e",t)
t = re.sub("è","e",t)
t = re.sub("ê","e",t)
t = re.sub("í","i",t)
t = re.sub("Á","A",t)
t = re.sub("À","A",t)
t = re.sub("É","E",t)
t = re.sub("È","E",t)
# replace UTF codes by utf chars
sts = re.split("\\\\(U\+....)",t)
ns = u""
for ss in sts:
print ss, type(ss)
if ss.startswith("U+"):
ucode = "0x"+ss[2:]
ns += unichr(eval(ucode))
else:
ns += ss.decode("utf8")
t = ns
# replace degrees, diameters chars
t = re.sub('%%d','°',t)
t = re.sub('%%c','Ø',t)
print "output text: ",t
return t
def locateLayer(wantedLayer):
@ -145,10 +137,10 @@ def calcBulge(v1,bulge,v2):
'''
chord = v2.sub(v1)
sagitta = (bulge * chord.Length)/2
startpoint = v1.add(DraftVecUtils.scale(chord,0.5))
perp = chord.cross(Vector(0,0,1))
startpoint = v1.add(chord.multiply(0.5))
if not DraftVecUtils.isNull(perp): perp.normalize()
endpoint = DraftVecUtils.scale(perp,sagitta)
endpoint = perp.multiply(sagitta)
return startpoint.add(endpoint)
def getGroup(ob):
@ -215,6 +207,7 @@ class fcformat:
self.stdSize = params.GetBool("dxfStdSize")
self.importDxfHatches = params.GetBool("importDxfHatches")
self.renderPolylineWidth = params.GetBool("renderPolylineWidth")
self.importPoints = params.GetBool("dxfImportPoints")
bparams = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/View")
if self.paramstyle > 1:
@ -231,7 +224,7 @@ class fcformat:
v1 = FreeCAD.Vector(r1,g1,b1)
v2 = FreeCAD.Vector(r2,g2,b2)
v = v2.sub(v1)
v = DraftVecUtils.scale(v,0.5)
v.multiply(0.5)
cv = v1.add(v)
else:
c1 = bparams.GetUnsigned("BackgroundColor")
@ -260,13 +253,13 @@ class fcformat:
if self.paramstyle == 3:
parammappingfile = params.GetString("dxfmappingfile")
self.table = self.buildTable(parammappingfile)
def buildTable(self,tablefile):
"builds a table for converting colors into linewidths"
try: f = pythonopen(tablefile)
except ValueError:
print "error: ",tablefile, " not found"
return None
print "error: ",tablefile, " not found"
return None
table = {}
header = len(f.readline().split("\t"))
if header == 15:
@ -300,13 +293,12 @@ class fcformat:
table = None
print table
return table
def formatObject(self,obj,dxfobj=None):
"applies color and linetype to objects"
if self.paramstyle == 0:
if hasattr(obj.ViewObject,"TextColor"):
obj.ViewObject.TextColor = (0.0,0.0,0.0)
elif self.paramstyle == 1:
if hasattr(obj.ViewObject,"TextColor"):
obj.ViewObject.TextColor = (0.0,0.0,0.0)
if self.paramstyle == 1:
if hasattr(obj.ViewObject,"TextColor"):
obj.ViewObject.TextColor = self.col
else:
@ -479,6 +471,38 @@ def drawCircle(circle,shapemode=False):
except:
warn(circle)
return None
def drawEllipse(ellipse):
"returns a Part shape from a dxf arc"
try:
c = vec(ellipse.loc)
start = round(ellipse.start_angle,prec())
end = round(ellipse.end_angle,prec())
majv = vec(ellipse.major)
majr = majv.Length
minr = majr*ellipse.ratio
el = Part.Ellipse(vec((0,0,0)),majr,minr)
x = majv.normalize()
z = vec(ellipse.extrusion).normalize()
y = z.cross(x)
m = DraftVecUtils.getPlaneRotation(x,y,z)
pl = FreeCAD.Placement(m)
pl.move(c)
if (fmt.paramstyle >= 4) and (not shapemode):
if (start != 0.0) or ((end != 0.0) or (end != round(math.pi/2,prec()))):
shape = el.toShape(start,end)
shape.Placement = pl
return shape
else:
return Draft.makeEllipse(majr,minr,pl)
else:
shape = el.toShape(start,end)
shape.Placement = pl
return shape
except:
warn(arc)
return None
def drawFace(face):
"returns a Part face from a list of points"
@ -605,7 +629,7 @@ def drawSpline(spline,shapemode=False):
warn(spline)
return None
def drawBlock(blockref,num=None):
def drawBlock(blockref,num=None,createObject=False):
"returns a shape from a dxf block reference"
if not fmt.paramstarblocks:
if blockref.name[0] == '*':
@ -650,31 +674,52 @@ def drawBlock(blockref,num=None):
except: warn(blockref)
if shape:
blockshapes[blockref.name]=shape
if createObject:
newob=doc.addObject("Part::Feature",blockref.name)
newob.Shape = shape
blockobjects[blockref.name] = newob
return newob
return shape
return None
def drawInsert(insert,num=None):
if blockshapes.has_key(insert):
shape = blockshapes[insert.block].copy()
else:
shape = None
for b in drawing.blocks.data:
if b.name == insert.block:
shape = drawBlock(b,num)
def drawInsert(insert,num=None,clone=False):
if fmt.paramtext:
attrs = attribs(insert)
for a in attrs:
addText(a,attrib=True)
if shape:
pos = vec(insert.loc)
rot = math.radians(insert.rotation)
scale = insert.scale
tsf = FreeCAD.Matrix()
tsf.scale(scale[0],scale[1],0) # for some reason z must be 0 to work
tsf.rotateZ(rot)
shape = shape.transformGeometry(tsf)
shape.translate(pos)
return shape
if clone:
if blockobjects.has_key(insert.block):
newob = Draft.clone(blockobjects[insert.block])
tsf = FreeCAD.Matrix()
rot = math.radians(insert.rotation)
pos = vec(insert.loc)
tsf.move(pos)
tsf.rotateZ(rot)
sc = insert.scale
sc = FreeCAD.Vector(sc[0],sc[1],0)
newob.Placement = FreeCAD.Placement(tsf)
newob.Scale = sc
return newob
else:
shape = None
else:
if blockshapes.has_key(insert):
shape = blockshapes[insert.block].copy()
else:
shape = None
for b in drawing.blocks.data:
if b.name == insert.block:
shape = drawBlock(b,num)
if shape:
pos = vec(insert.loc)
rot = math.radians(insert.rotation)
scale = insert.scale
tsf = FreeCAD.Matrix()
tsf.scale(scale[0],scale[1],0) # for some reason z must be 0 to work
tsf.rotateZ(rot)
shape = shape.transformGeometry(tsf)
shape.translate(pos)
return shape
return None
def drawLayerBlock(objlist):
@ -743,28 +788,54 @@ def addText(text,attrib=False):
newob = doc.addObject("App::Annotation","Text")
lay.addObject(newob)
val = deformat(val)
#val = val.decode("Latin1").encode("Latin1")
# the following stores text as Latin1 in annotations, which
# displays ok in coin texts, but causes errors later on.
# better store as utf8 always.
#try:
# val = val.decode("utf8").encode("Latin1")
#except:
# try:
# val = val.encode("latin1")
# except:
# pass
rx = rawValue(text,11)
ry = rawValue(text,21)
rz = rawValue(text,31)
xv = Vector(1,0,0)
ax = Vector(0,0,1)
if rx or ry or rz:
xv = Vector(rx,ry,rz)
if not DraftVecUtils.isNull(xv):
ax = DraftVecUtils.neg(xv.cross(Vector(1,0,0)))
ax = (xv.cross(Vector(1,0,0))).negative()
if DraftVecUtils.isNull(ax):
ax = Vector(0,0,1)
ang = -math.degrees(DraftVecUtils.angle(xv,Vector(1,0,0),ax))
Draft.rotate(newob,ang,axis=ax)
if ax == Vector(0,0,-1): ax = Vector(0,0,1)
elif hasattr(text,"rotation"):
if text.rotation:
Draft.rotate(newob,text.rotation)
if attrib:
attrot = rawValue(text,50)
if attrot:
Draft.rotate(newob,attrot)
newob.LabelText = val.split("\n")
if gui and fmt.stdSize:
fsize = FreeCADGui.draftToolBar.fontsize
else:
fsize = float(hgt)*TEXTSCALING
if hasattr(text,"alignment"):
yv = ax.cross(xv)
if text.alignment in [1,2,3]:
sup = DraftVecUtils.scaleTo(yv,fsize/TEXTSCALING).negative()
print ax,sup
pos = pos.add(sup)
elif text.alignment in [4,5,6]:
sup = DraftVecUtils.scaleTo(yv,fsize/(2*TEXTSCALING)).negative()
pos = pos.add(sup)
newob.Position = pos
if gui:
if fmt.stdSize:
newob.ViewObject.FontSize = FreeCADGui.draftToolBar.fontsize
else:
newob.ViewObject.FontSize = float(hgt)
newob.ViewObject.FontSize = fsize
if hasattr(text,"alignment"):
if text.alignment in [2,5,8]:
newob.ViewObject.Justification = "Center"
@ -791,6 +862,8 @@ def processdxf(document,filename):
doc = document
global blockshapes
blockshapes = {}
global blockobjects
blockobjects = {}
global badobjects
badobjects = []
global layerBlocks
@ -830,7 +903,7 @@ def processdxf(document,filename):
else:
newob = addObject(shape,"Line",line.layer)
if gui: fmt.formatObject(newob,line)
# drawing polylines
pls = drawing.entities.get_type("lwpolyline")
@ -876,7 +949,7 @@ def processdxf(document,filename):
newob = addObject(shape,"Polyline",polyline.layer)
if gui: fmt.formatObject(newob,polyline)
num += 1
# drawing arcs
arcs = drawing.entities.get_type("arc")
@ -968,6 +1041,21 @@ def processdxf(document,filename):
else:
newob = addObject(shape,"Spline",lay)
if gui: fmt.formatObject(newob,spline)
# drawing ellipses
ellipses = drawing.entities.get_type("ellipse")
if ellipses: FreeCAD.Console.PrintMessage("drawing "+str(len(ellipses))+" ellipses...\n")
for ellipse in ellipses:
lay = rawValue(ellipse,8)
if fmt.dxflayout or (not rawValue(ellipse,67)):
shape = drawEllipse(ellipse)
if shape:
if fmt.makeBlocks:
addToBlock(shape,lay)
else:
newob = addObject(shape,"Ellipse",lay)
if gui: fmt.formatObject(newob,ellipse)
# drawing texts
@ -979,7 +1067,7 @@ def processdxf(document,filename):
for text in texts:
if fmt.dxflayout or (not rawValue(text,67)):
addText(text)
else: FreeCAD.Console.PrintMessage("skipping texts...\n")
# drawing 3D objects
@ -1032,6 +1120,12 @@ def processdxf(document,filename):
pt = FreeCAD.Vector(x1,y1,z1)
p1 = FreeCAD.Vector(x2,y2,z2)
p2 = FreeCAD.Vector(x3,y3,z3)
if align >= 128:
align -= 128
elif align >= 64:
align -= 64
elif align >= 32:
align -= 32
if align == 0:
if angle in [0,180]:
p2 = FreeCAD.Vector(x3,y2,z2)
@ -1052,29 +1146,32 @@ def processdxf(document,filename):
newob.ViewObject.FontSize = FreeCADGui.draftToolBar.fontsize
else:
st = rawValue(dim,3)
newob.ViewObject.FontSize = float(getdimheight(st))
else: FreeCAD.Console.PrintMessage("skipping dimensions...\n")
newob.ViewObject.FontSize = float(getdimheight(st))*TEXTSCALING
else:
FreeCAD.Console.PrintMessage("skipping dimensions...\n")
# drawing points
points = drawing.entities.get_type("point")
if points: FreeCAD.Console.PrintMessage("drawing "+str(len(points))+" points...\n")
for point in points:
x = rawValue(point,10)
y = rawValue(point,20)
z = rawValue(point,30)
lay = rawValue(point,8)
if fmt.dxflayout or (not rawValue(point,67)):
if fmt.makeBlocks:
shape = Part.Vertex(x,y,z)
addToBlock(shape,lay)
else:
newob = Draft.makePoint(x,y,z)
lay = locateLayer(lay)
lay.addObject(newob)
if gui:
fmt.formatObject(newob,point)
if fmt.importPoints:
points = drawing.entities.get_type("point")
if points: FreeCAD.Console.PrintMessage("drawing "+str(len(points))+" points...\n")
for point in points:
x = rawValue(point,10)
y = rawValue(point,20)
z = rawValue(point,30)
lay = rawValue(point,8)
if fmt.dxflayout or (not rawValue(point,67)):
if fmt.makeBlocks:
shape = Part.Vertex(x,y,z)
addToBlock(shape,lay)
else:
newob = Draft.makePoint(x,y,z)
lay = locateLayer(lay)
lay.addObject(newob)
if gui:
fmt.formatObject(newob,point)
else:
FreeCAD.Console.PrintMessage("skipping points...\n")
# drawing leaders
@ -1139,10 +1236,16 @@ def processdxf(document,filename):
FreeCAD.Console.PrintMessage("drawing "+str(len(inserts))+" blocks...\n")
blockrefs = drawing.blocks.data
for ref in blockrefs:
drawBlock(ref)
if fmt.paramstyle >= 4:
drawBlock(ref,createObject=True)
else:
drawBlock(ref,createObject=False)
num = 0
for insert in inserts:
shape = drawInsert(insert,num)
if (fmt.paramstyle >= 4) and not(fmt.makeBlocks):
shape = drawInsert(insert,num,clone=True)
else:
shape = drawInsert(insert,num)
if shape:
if fmt.makeBlocks:
addToBlock(shape,insert.layer)
@ -1160,7 +1263,14 @@ def processdxf(document,filename):
if shape:
newob = addObject(shape,k)
del layerBlocks
# hide block objects, if any
for k,o in blockobjects.iteritems():
if o.ViewObject:
o.ViewObject.hide()
del blockobjects
# finishing
print "done processing"
@ -1396,6 +1506,22 @@ def writeShape(sh,ob,dxfobject,nospline=False):
dxfobject.append(dxfLibrary.Arc(center, radius,
ang1, ang2, color=getACI(ob),
layer=getGroup(ob)))
elif DraftGeomUtils.geomType(edge) == "Ellipse": # ellipses:
if hasattr(dxfLibrary,"Ellipse"):
center = DraftVecUtils.tup(edge.Curve.Center)
norm = DraftVecUtils.tup(edge.Curve.Axis)
start = edge.FirstParameter
end = edge.LastParameter
ax = edge.Curve.Focus1.sub(edge.Curve.Center)
major = DraftVecUtils.tup(DraftVecUtils.scaleTo(ax,edge.Curve.MajorRadius))
minor = edge.Curve.MinorRadius/edge.Curve.MajorRadius
dxfobject.append(dxfLibrary.Ellipse(center=center,majorAxis=major,normalAxis=norm,
minorAxisRatio=minor,startParameter=start,
endParameter=end,
color=getACI(ob),
layer=getGroup(ob)))
else:
FreeCAD.Console.PrintWarning("Ellipses support not found. Please delete dxfLibrary.py from your FreeCAD user directory to force auto-update\n")
else: # anything else is treated as lines
if len(edge.Vertexes) > 1:
ve1=edge.Vertexes[0].Point
@ -1424,7 +1550,11 @@ def export(objectslist,filename,nospline=False):
global exportList
exportList = objectslist
print exportList
exportList = Draft.getGroupContents(exportList)
print exportList
if (len(exportList) == 1) and (Draft.getType(exportList[0]) == "ArchSectionView"):
# arch view: export it "as is"
@ -1500,7 +1630,7 @@ def export(objectslist,filename,nospline=False):
if not proj:
pbase = DraftVecUtils.tup(ob.End)
else:
pbase = DraftVecUtils.tup(ob.End.add(DraftVecUtils.neg(proj)))
pbase = DraftVecUtils.tup(ob.End.add(proj.negative()))
dxf.append(dxfLibrary.Dimension(pbase,p1,p2,color=getACI(ob),
layer=getGroup(ob)))

View File

@ -320,7 +320,7 @@ def arcend2center(lastvec,currentvec,rx,ry,xrotation=0.0,correction=False):
rx = float(rx)
ry = float(ry)
v0 = lastvec.sub(currentvec)
v0 = v0.multiply(0.5)
v0.multiply(0.5)
m1=FreeCAD.Matrix()
m1.rotateZ(-xrotation) #Formular 6.5.1
v1=m1.multiply(v0)
@ -335,19 +335,19 @@ def arcend2center(lastvec,currentvec,rx,ry,xrotation=0.0,correction=False):
results=[]
if abs(numer/denom) < 10**(-1*(Draft.precision())):
scalefacpos = 0
else:
try:
scalefacpos = math.sqrt(numer/denom)
except ValueError:
else:
try:
scalefacpos = math.sqrt(numer/denom)
except ValueError:
FreeCAD.Console.PrintMessage('sqrt(%f/%f)\n' % (numer,denom))
scalefacpos = 0
scalefacpos = 0
for scalefacsign in (1,-1):
scalefac = scalefacpos * scalefacsign
vcx1 = Vector(v1.y*rx/ry,-v1.x*ry/rx,0).multiply(scalefac) # Step2 F.6.5.2
m2=FreeCAD.Matrix()
m2.rotateZ(xrotation)
centeroff = currentvec.add(lastvec)
centeroff = DraftVecUtils.scale(centeroff,.5)
centeroff.multiply(.5)
vcenter = m2.multiply(vcx1).add(centeroff) # Step3 F.6.5.3
#angle1 = Vector(1,0,0).getAngle(Vector((v1.x-vcx1.x)/rx,(v1.y-vcx1.y)/ry,0)) # F.6.5.5
#angledelta = Vector((v1.x-vcx1.x)/rx,(v1.y-vcx1.y)/ry,0).getAngle(Vector((-v1.x-vcx1.x)/rx,(-v1.y-vcx1.y)/ry,0)) # F.6.5.6
@ -359,19 +359,19 @@ def arcend2center(lastvec,currentvec,rx,ry,xrotation=0.0,correction=False):
def getrgb(color):
"returns a rgb value #000000 from a freecad color"
r = str(hex(int(color[0]*255)))[2:].zfill(2)
g = str(hex(int(color[1]*255)))[2:].zfill(2)
b = str(hex(int(color[2]*255)))[2:].zfill(2)
return "#"+r+g+b
"returns a rgb value #000000 from a freecad color"
r = str(hex(int(color[0]*255)))[2:].zfill(2)
g = str(hex(int(color[1]*255)))[2:].zfill(2)
b = str(hex(int(color[2]*255)))[2:].zfill(2)
return "#"+r+g+b
class svgHandler(xml.sax.ContentHandler):
"this handler parses the svg files and creates freecad objects"
"this handler parses the svg files and creates freecad objects"
def __init__(self):
"retrieving Draft parameters"
params = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Draft")
self.style = params.GetInt("svgstyle")
def __init__(self):
"retrieving Draft parameters"
params = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Draft")
self.style = params.GetInt("svgstyle")
self.count = 0
self.transform = None
self.grouptransform = []
@ -380,42 +380,44 @@ class svgHandler(xml.sax.ContentHandler):
global Part
import Part
if gui and draftui:
r = float(draftui.color.red()/255.0)
g = float(draftui.color.green()/255.0)
b = float(draftui.color.blue()/255.0)
self.lw = float(draftui.linewidth)
else:
self.lw = float(params.GetInt("linewidth"))
c = params.GetUnsigned("color")
r = float(((c>>24)&0xFF)/255)
g = float(((c>>16)&0xFF)/255)
b = float(((c>>8)&0xFF)/255)
self.col = (r,g,b,0.0)
if gui and draftui:
r = float(draftui.color.red()/255.0)
g = float(draftui.color.green()/255.0)
b = float(draftui.color.blue()/255.0)
self.lw = float(draftui.linewidth)
else:
self.lw = float(params.GetInt("linewidth"))
c = params.GetUnsigned("color")
r = float(((c>>24)&0xFF)/255)
g = float(((c>>16)&0xFF)/255)
b = float(((c>>8)&0xFF)/255)
self.col = (r,g,b,0.0)
def format(self,obj):
"applies styles to passed object"
if self.style and gui:
v = obj.ViewObject
if self.color: v.LineColor = self.color
if self.width: v.LineWidth = self.width
if self.fill: v.ShapeColor = self.fill
def startElement(self, name, attrs):
def format(self,obj):
"applies styles to passed object"
if self.style and gui:
v = obj.ViewObject
if self.color: v.LineColor = self.color
if self.width: v.LineWidth = self.width
if self.fill: v.ShapeColor = self.fill
def startElement(self, name, attrs):
# reorganizing data into a nice clean dictionary
# reorganizing data into a nice clean dictionary
self.count += 1
FreeCAD.Console.PrintMessage('processing element %d: %s\n'%(self.count,name))
FreeCAD.Console.PrintMessage('existing group transform: %s\n'%(str(self.grouptransform)))
data = {}
for (keyword,content) in attrs.items():
content = content.replace(',',' ')
content = content.split()
data[keyword]=content
data = {}
for (keyword,content) in attrs.items():
#print keyword,content
content = content.replace(',',' ')
content = content.split()
#print keyword,content
data[keyword]=content
if 'style' in data:
if not data['style']:
@ -425,24 +427,27 @@ class svgHandler(xml.sax.ContentHandler):
content = content.split(';')
for i in content:
pair = i.split(':')
if len(pair)>1: data[pair[0]]=pair[1]
if len(pair)>1: data[pair[0]]=pair[1]
for k in ['x','y','x1','y1','x2','y2','r','rx','ry','cx','cy','width','height']:
if k in data:
data[k] = getsize(data[k][0],'css')
for k in ['x','y','x1','y1','x2','y2','r','rx','ry','cx','cy','width','height']:
if k in data:
data[k] = getsize(data[k][0],'css')
for k in ['fill','stroke','stroke-width','font-size']:
if k in data:
if isinstance(data[k],list):
data[k]=data[k][0]
for k in ['fill','stroke','stroke-width','font-size']:
if k in data:
if isinstance(data[k],list):
if data[k][0].lower().startswith("rgb("):
data[k] = ",".join(data[k])
else:
data[k]=data[k][0]
# extracting style info
self.fill = None
self.color = None
self.width = None
self.text = None
# extracting style info
self.fill = None
self.color = None
self.width = None
self.text = None
if name == 'svg':
m=FreeCAD.Matrix()
if 'width' in data and 'height' in data and \
@ -481,16 +486,16 @@ class svgHandler(xml.sax.ContentHandler):
#fallback to 90 dpi
m.scale(Vector(25.4/90.0,25.4/90.0,1))
self.grouptransform.append(m)
if 'fill' in data:
if data['fill'][0] != 'none':
self.fill = getcolor(data['fill'])
if 'stroke' in data:
if data['stroke'][0] != 'none':
self.color = getcolor(data['stroke'])
if 'stroke-width' in data:
if data['stroke-width'] != 'none':
self.width = getsize(data['stroke-width'],'css')
if 'transform' in data:
if 'fill' in data:
if data['fill'][0] != 'none':
self.fill = getcolor(data['fill'])
if 'stroke' in data:
if data['stroke'][0] != 'none':
self.color = getcolor(data['stroke'])
if 'stroke-width' in data:
if data['stroke-width'] != 'none':
self.width = getsize(data['stroke-width'],'css')
if 'transform' in data:
m = self.getMatrix(attrs.getValue('transform'))
if name == "g":
self.grouptransform.append(m)
@ -500,29 +505,29 @@ class svgHandler(xml.sax.ContentHandler):
if name == "g":
self.grouptransform.append(FreeCAD.Matrix())
if (self.style == 1):
self.color = self.col
self.width = self.lw
if (self.style == 1):
self.color = self.col
self.width = self.lw
pathname = None
if 'id' in data:
pathname = data['id'][0]
FreeCAD.Console.PrintMessage('name: %s\n'%pathname)
# processing paths
# processing paths
if name == "path":
if name == "path":
FreeCAD.Console.PrintMessage('data: %s\n'%str(data))
if not pathname: pathname = 'Path'
path = []
point = []
lastvec = Vector(0,0,0)
lastpole = None
command = None
relative = False
firstvec = None
path = []
point = []
lastvec = Vector(0,0,0)
lastpole = None
command = None
relative = False
firstvec = None
if "freecad:basepoint1" in data:
p1 = data["freecad:basepoint1"]
@ -616,11 +621,11 @@ class svgHandler(xml.sax.ContentHandler):
else:
# anticlockwise
perp = DraftVecUtils.rotate2D(chord,math.pi/2)
chord = DraftVecUtils.scale(chord,.5)
chord.multiply(.5)
if chord.Length > rx: a = 0
else: a = math.sqrt(rx**2-chord.Length**2)
s = rx - a
perp = DraftVecUtils.scale(perp,s/perp.Length)
perp.multiply(s/perp.Length)
midpoint = lastvec.add(chord.add(perp))
seg = Part.Arc(lastvec,midpoint,currentvec).toShape()
else:# big arc or elliptical arc
@ -748,7 +753,11 @@ class svgHandler(xml.sax.ContentHandler):
path.append(seg)
elif (d == "Z") or (d == "z"):
if not DraftVecUtils.equals(lastvec,firstvec):
try:
seg = Part.Line(lastvec,firstvec).toShape()
except:
pass
else:
path.append(seg)
if path: #the path should be closed by now
#sh=makewire(path,True)
@ -774,9 +783,9 @@ class svgHandler(xml.sax.ContentHandler):
self.format(obj)
# processing rects
# processing rects
if name == "rect":
if name == "rect":
if not pathname: pathname = 'Rectangle'
edges = []
if ('rx' not in data or data['rx'] < 10**(-1*Draft.precision())) and \
@ -847,37 +856,37 @@ class svgHandler(xml.sax.ContentHandler):
self.format(obj)
# processing lines
if name == "line":
if name == "line":
if not pathname: pathname = 'Line'
p1 = Vector(data['x1'],-data['y1'],0)
p2 = Vector(data['x2'],-data['y2'],0)
sh = Part.Line(p1,p2).toShape()
p1 = Vector(data['x1'],-data['y1'],0)
p2 = Vector(data['x2'],-data['y2'],0)
sh = Part.Line(p1,p2).toShape()
sh = self.applyTrans(sh)
obj = self.doc.addObject("Part::Feature",pathname)
obj.Shape = sh
self.format(obj)
obj = self.doc.addObject("Part::Feature",pathname)
obj.Shape = sh
self.format(obj)
# processing polylines and polygons
if name == "polyline" or name == "polygon":
'''a simpler implementation would be sh = Part.makePolygon([Vector(svgx,-svgy,0) for svgx,svgy in zip(points[0::2],points[1::2])])
but there would be more difficlult to search for duplicate points beforehand.'''
if not pathname: pathname = 'Polyline'
points=[float(d) for d in data['points']]
if name == "polyline" or name == "polygon":
'''a simpler implementation would be sh = Part.makePolygon([Vector(svgx,-svgy,0) for svgx,svgy in zip(points[0::2],points[1::2])])
but there would be more difficlult to search for duplicate points beforehand.'''
if not pathname: pathname = 'Polyline'
points=[float(d) for d in data['points']]
FreeCAD.Console.PrintMessage('points %s\n'%str(points))
lenpoints=len(points)
if lenpoints>=4 and lenpoints % 2 == 0:
lastvec = Vector(points[0],-points[1],0)
path=[]
lenpoints=len(points)
if lenpoints>=4 and lenpoints % 2 == 0:
lastvec = Vector(points[0],-points[1],0)
path=[]
if name == 'polygon':
points=points+points[:2] # emulate closepath
for svgx,svgy in zip(points[2::2],points[3::2]):
currentvec = Vector(svgx,-svgy,0)
if not DraftVecUtils.equals(lastvec,currentvec):
seg = Part.Line(lastvec,currentvec).toShape()
#print "polyline seg ",lastvec,currentvec
lastvec = currentvec
path.append(seg)
for svgx,svgy in zip(points[2::2],points[3::2]):
currentvec = Vector(svgx,-svgy,0)
if not DraftVecUtils.equals(lastvec,currentvec):
seg = Part.Line(lastvec,currentvec).toShape()
#print "polyline seg ",lastvec,currentvec
lastvec = currentvec
path.append(seg)
if path:
sh = Part.Wire(path)
if self.fill and sh.isClosed():
@ -908,9 +917,9 @@ class svgHandler(xml.sax.ContentHandler):
sh = Part.Wire([sh])
sh = Part.Face(sh)
sh = self.applyTrans(sh)
obj = self.doc.addObject("Part::Feature",pathname)
obj.Shape = sh
self.format(obj)
obj = self.doc.addObject("Part::Feature",pathname)
obj.Shape = sh
self.format(obj)
# processing circles
@ -925,13 +934,13 @@ class svgHandler(xml.sax.ContentHandler):
sh = Part.Face(sh)
sh.translate(c)
sh = self.applyTrans(sh)
obj = self.doc.addObject("Part::Feature",pathname)
obj.Shape = sh
self.format(obj)
obj = self.doc.addObject("Part::Feature",pathname)
obj.Shape = sh
self.format(obj)
# processing texts
if name in ["text","tspan"]:
if name in ["text","tspan"]:
if not("freecad:skip" in data):
FreeCAD.Console.PrintMessage("processing a text\n")
if 'x' in data:
@ -953,12 +962,12 @@ class svgHandler(xml.sax.ContentHandler):
FreeCAD.Console.PrintMessage("done processing element %d\n"%self.count)
def characters(self,content):
if self.text:
def characters(self,content):
if self.text:
FreeCAD.Console.PrintMessage("reading characters %s\n" % str(content))
obj=self.doc.addObject("App::Annotation",'Text')
obj.LabelText = content.encode('latin1')
vec = Vector(self.x,-self.y,0)
obj=self.doc.addObject("App::Annotation",'Text')
obj.LabelText = content.encode('latin1')
vec = Vector(self.x,-self.y,0)
if self.transform:
vec = self.translateVec(vec,self.transform)
#print "own transform: ",self.transform, vec
@ -967,10 +976,10 @@ class svgHandler(xml.sax.ContentHandler):
vec = transform.multiply(vec)
#print "applying vector: ",vec
obj.Position = vec
if gui:
obj.ViewObject.FontSize = int(self.text)
if self.fill: obj.ViewObject.TextColor = self.fill
else: obj.ViewObject.TextColor = (0.0,0.0,0.0,0.0)
if gui:
obj.ViewObject.FontSize = int(self.text)
if self.fill: obj.ViewObject.TextColor = self.fill
else: obj.ViewObject.TextColor = (0.0,0.0,0.0,0.0)
def endElement(self, name):
if not name in ["tspan"]:
@ -1010,41 +1019,41 @@ class svgHandler(xml.sax.ContentHandler):
def getMatrix(self,tr):
"returns a FreeCAD matrix from a svg transform attribute"
transformre=re.compile('(matrix|translate|scale|rotate|skewX|skewY)\s*?\((.*?)\)',re.DOTALL)
transformre=re.compile('(matrix|translate|scale|rotate|skewX|skewY)\s*?\((.*?)\)',re.DOTALL)
m = FreeCAD.Matrix()
for transformation, arguments in transformre.findall(tr):
argsplit=[float(arg) for arg in arguments.replace(',',' ').split()]
argsplit=[float(arg) for arg in arguments.replace(',',' ').split()]
#m.multiply(FreeCAD.Matrix (1,0,0,0,0,-1))
#print '%s:%s %s %d' % (transformation, arguments,argsplit,len(argsplit))
if transformation == 'translate':
tx = argsplit[0]
ty = argsplit[1] if len(argsplit) > 1 else 0.0
m.move(Vector(tx,-ty,0))
elif transformation == 'scale':
sx = argsplit[0]
sy = argsplit[1] if len(argsplit) > 1 else sx
m.scale(Vector(sx,sy,1))
elif transformation == 'rotate':
angle = argsplit[0]
if len(argsplit) >= 3:
cx = argsplit[1]
cy = argsplit[2]
m.move(Vector(cx,-cy,0))
if transformation == 'translate':
tx = argsplit[0]
ty = argsplit[1] if len(argsplit) > 1 else 0.0
m.move(Vector(tx,-ty,0))
elif transformation == 'scale':
sx = argsplit[0]
sy = argsplit[1] if len(argsplit) > 1 else sx
m.scale(Vector(sx,sy,1))
elif transformation == 'rotate':
angle = argsplit[0]
if len(argsplit) >= 3:
cx = argsplit[1]
cy = argsplit[2]
m.move(Vector(cx,-cy,0))
m.rotateZ(math.radians(-angle)) #mirroring one axis equals changing the direction of rotaion
if len(argsplit) >= 3:
m.move(Vector(-cx,cy,0))
elif transformation == 'skewX':
m=m.multiply(FreeCAD.Matrix(1,-math.tan(math.radians(argsplit[0]))))
elif transformation == 'skewY':
m=m.multiply(FreeCAD.Matrix(1,0,0,0,-math.tan(math.radians(argsplit[0]))))
elif transformation == 'matrix':
if len(argsplit) >= 3:
m.move(Vector(-cx,cy,0))
elif transformation == 'skewX':
m=m.multiply(FreeCAD.Matrix(1,-math.tan(math.radians(argsplit[0]))))
elif transformation == 'skewY':
m=m.multiply(FreeCAD.Matrix(1,0,0,0,-math.tan(math.radians(argsplit[0]))))
elif transformation == 'matrix':
# '''transformation matrix:
# FreeCAD SVG
# (+A -C +0 +E) (A C 0 E)
# (-B +D -0 -F) = (-Y) * (B D 0 F) *(-Y)
# (+0 -0 +1 +0) (0 0 1 0)
# (+0 -0 +0 +1) (0 0 0 1)'''
m=m.multiply(FreeCAD.Matrix(argsplit[0],-argsplit[2],0,argsplit[4],-argsplit[1],argsplit[3],0,-argsplit[5]))
m=m.multiply(FreeCAD.Matrix(argsplit[0],-argsplit[2],0,argsplit[4],-argsplit[1],argsplit[3],0,-argsplit[5]))
#else:
#print 'SKIPPED %s' % transformation
#print "m= ",m
@ -1052,17 +1061,17 @@ class svgHandler(xml.sax.ContentHandler):
return m
def decodeName(name):
"decodes encoded strings"
try:
decodedName = (name.decode("utf8"))
except UnicodeDecodeError:
try:
decodedName = (name.decode("latin1"))
except UnicodeDecodeError:
FreeCAD.Console.PrintError("svg: error: couldn't determine character encoding\n")
"decodes encoded strings"
try:
decodedName = (name.decode("utf8"))
except UnicodeDecodeError:
try:
decodedName = (name.decode("latin1"))
except UnicodeDecodeError:
FreeCAD.Console.PrintError("svg: error: couldn't determine character encoding\n")
decodedName = name
return decodedName
decodedName = name
return decodedName
def getContents(filename,tag,stringmode=False):
"gets the contents of all the occurences of the given tag in the given file"
@ -1087,50 +1096,50 @@ def getContents(filename,tag,stringmode=False):
return result
def open(filename):
docname=os.path.split(filename)[1]
doc=FreeCAD.newDocument(docname)
doc.Label = decodeName(docname[:-4])
parser = xml.sax.make_parser()
parser.setContentHandler(svgHandler())
parser._cont_handler.doc = doc
docname=os.path.split(filename)[1]
doc=FreeCAD.newDocument(docname)
doc.Label = decodeName(docname[:-4])
parser = xml.sax.make_parser()
parser.setContentHandler(svgHandler())
parser._cont_handler.doc = doc
f = pythonopen(filename)
parser.parse(f)
parser.parse(f)
f.close()
doc.recompute()
doc.recompute()
return doc
def insert(filename,docname):
try:
doc=FreeCAD.getDocument(docname)
except:
doc=FreeCAD.newDocument(docname)
FreeCAD.ActiveDocument = doc
parser = xml.sax.make_parser()
parser.setContentHandler(svgHandler())
parser._cont_handler.doc = doc
parser.parse(pythonopen(filename))
doc.recompute()
try:
doc=FreeCAD.getDocument(docname)
except:
doc=FreeCAD.newDocument(docname)
FreeCAD.ActiveDocument = doc
parser = xml.sax.make_parser()
parser.setContentHandler(svgHandler())
parser._cont_handler.doc = doc
parser.parse(pythonopen(filename))
doc.recompute()
def export(exportList,filename):
"called when freecad exports a file"
"called when freecad exports a file"
svg_export_style = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Draft").GetInt("svg_export_style")
if svg_export_style != 0 and svg_export_style != 1:
FreeCAD.Console.PrintMessage("unknown svg export style, switching to Translated\n")
svg_export_style = 0
# finding sheet size
minx = 10000
miny = 10000
maxx = 0
maxy = 0
for ob in exportList:
if ob.isDerivedFrom("Part::Feature"):
for v in ob.Shape.Vertexes:
if v.Point.x < minx: minx = v.Point.x
if v.Point.x > maxx: maxx = v.Point.x
if v.Point.y < miny: miny = v.Point.y
if v.Point.y > maxy: maxy = v.Point.y
# finding sheet size
minx = 10000
miny = 10000
maxx = 0
maxy = 0
for ob in exportList:
if ob.isDerivedFrom("Part::Feature"):
for v in ob.Shape.Vertexes:
if v.Point.x < minx: minx = v.Point.x
if v.Point.x > maxx: maxx = v.Point.x
if v.Point.y < miny: miny = v.Point.y
if v.Point.y > maxy: maxy = v.Point.y
if svg_export_style == 0:
# translated-style exports get a bit of a margin
margin = (maxx-minx)*.01
@ -1138,23 +1147,23 @@ def export(exportList,filename):
# raw-style exports get no margin
margin = 0
minx -= margin
maxx += margin
miny -= margin
maxy += margin
sizex = maxx-minx
sizey = maxy-miny
miny += margin
minx -= margin
maxx += margin
miny -= margin
maxy += margin
sizex = maxx-minx
sizey = maxy-miny
miny += margin
# writing header
# writing header
# we specify the svg width and height in FreeCAD's physical units (mm),
# and specify the viewBox so that user units maps one-to-one to mm
svg = pythonopen(filename,'wb')
svg.write('<?xml version="1.0"?>\n')
svg.write('<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"')
svg.write(' "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\n')
svg.write('<svg')
svg.write(' width="' + str(sizex) + 'mm" height="' + str(sizey) + 'mm"')
svg = pythonopen(filename,'wb')
svg.write('<?xml version="1.0"?>\n')
svg.write('<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"')
svg.write(' "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\n')
svg.write('<svg')
svg.write(' width="' + str(sizex) + 'mm" height="' + str(sizey) + 'mm"')
if svg_export_style == 0:
# translated-style exports have the viewbox starting at X=0, Y=0
svg.write(' viewBox="0 0 ' + str(sizex) + ' ' + str(sizey) + '"')
@ -1163,11 +1172,11 @@ def export(exportList,filename):
# we need the funny Y here because SVG is upside down, and we
# flip the sketch right-way up with a scale later
svg.write(' viewBox="0 ' + str(sizey * -1.0) + ' ' + str(sizex) + ' ' + str(sizey) + '"')
svg.write(' xmlns="http://www.w3.org/2000/svg" version="1.1"')
svg.write('>\n')
svg.write(' xmlns="http://www.w3.org/2000/svg" version="1.1"')
svg.write('>\n')
# writing paths
for ob in exportList:
# writing paths
for ob in exportList:
if svg_export_style == 0:
# translated-style exports have the entire sketch translated to fit in the X>0, Y>0 quadrant
svg.write('<g transform="translate('+str(-minx)+','+str(-miny+(2*margin))+') scale(1,-1)">\n')
@ -1177,6 +1186,6 @@ def export(exportList,filename):
svg.write(Draft.getSVG(ob))
svg.write('</g>\n')
# closing
svg.write('</svg>')
svg.close()
# closing
svg.write('</svg>')
svg.close()

View File

@ -25,47 +25,29 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <stdio.h>
# if defined (_POSIX_C_SOURCE)
# undef _POSIX_C_SOURCE
# endif // (re-)defined in pyconfig.h
# include <Python.h>
#endif
#include <Base/Console.h>
#include <Base/Interpreter.h>
#include <App/Application.h>
#include <Mod/Part/App/TopologyPy.h>
#include "FeatureImportStep.h"
#include "FeatureImportIges.h"
/* registration table */
extern struct PyMethodDef Import_methods[];
extern struct PyMethodDef Import_Import_methods[];
// python entry
#ifdef FC_OS_WIN32
# define ModuleExport __declspec(dllexport)
#else
# define ModuleExport
#endif
extern "C" {
void ModuleExport initImport() {
void ImportExport initImport()
{
(void) Py_InitModule("Import", Import_Import_methods); /* mod name, table ptr */
(void) Py_InitModule("Import", Import_methods); /* mod name, table ptr */
try {
Base::Interpreter().loadModule("Part");
}
catch(const Base::Exception& e) {
PyErr_SetString(PyExc_ImportError, e.what());
return;
}
// load dependend module
Base::Interpreter().loadModule("Part");
App::AbstractFeatureFactory().AddProducer("ImportStep",new App::AbstractFeatureProducer<Import::FeatureImportStep>);
App::AbstractFeatureFactory().AddProducer("ImportIges",new App::AbstractFeatureProducer<Import::FeatureImportIges>);
Base::Console().Log("Import loaded\n");
return;
Base::Console().Log("Loading Import module... done\n");
}

View File

@ -1,118 +1,264 @@
/***************************************************************************
* (c) Jürgen Riegel (juergen.riegel@web.de) 2002 *
* Copyright (c) 2013 Werner Mayer <wmayer[at]users.sourceforge.net> *
* *
* 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. *
* 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. *
* *
* FreeCAD is distributed in the hope that it will be useful, *
* 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 FreeCAD; if not, write to the Free Software *
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
* USA *
* 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 *
* *
* Juergen Riegel 2002 *
***************************************************************************/
#include "PreCompiled.h"
#if defined(__MINGW32__)
# define WNT // avoid conflict with GUID
#endif
#ifndef _PreComp_
# include <stdio.h>
# if defined (_POSIX_C_SOURCE)
# undef _POSIX_C_SOURCE
# endif // (re-)defined in pyconfig.h
# include <Python.h>
# include <BRep_Builder.hxx>
# include <BRepTools.hxx>
# include <Python.h>
# include <climits>
# include <Standard_Version.hxx>
# include <Handle_TDocStd_Document.hxx>
# include <Handle_XCAFApp_Application.hxx>
# include <TDocStd_Document.hxx>
# include <XCAFApp_Application.hxx>
# include <STEPCAFControl_Reader.hxx>
# include <STEPCAFControl_Writer.hxx>
# include <STEPControl_Writer.hxx>
# include <IGESCAFControl_Reader.hxx>
# include <IGESCAFControl_Writer.hxx>
# include <IGESControl_Controller.hxx>
# include <Interface_Static.hxx>
# include <Transfer_TransientProcess.hxx>
# include <XSControl_WorkSession.hxx>
# include <APIHeaderSection_MakeHeader.hxx>
# include <OSD_Exception.hxx>
#endif
#include "ImportOCAF.h"
#include <Base/PyObjectBase.h>
#include <Base/Console.h>
#include <Base/Interpreter.h>
#include <App/Application.h>
#include <App/Document.h>
#include <App/Feature.h>
#include <App/Property.h>
#include <Mod/Part/App/TopologyPy.h>
#include <App/DocumentObjectPy.h>
#include <Mod/Part/App/PartFeature.h>
#include <Mod/Part/App/ProgressIndicator.h>
#include <Mod/Part/App/ImportIges.h>
#include <Mod/Part/App/ImportStep.h>
/* module functions */
static PyObject *
open(PyObject *self, PyObject *args)
static PyObject * importer(PyObject *self, PyObject *args)
{
const char* Name;
if (! PyArg_ParseTuple(args, "s",&Name))
return NULL;
char* Name;
char* DocName=0;
if (!PyArg_ParseTuple(args, "s|s",&Name,&DocName))
return 0;
Base::Console().Log("Open in Import with %s",Name);
PY_TRY {
//Base::Console().Log("Insert in Part with %s",Name);
Base::FileInfo file(Name);
// extract ending
std::string cEnding(Name);
unsigned int pos = cEnding.find_last_of('.');
if(pos == cEnding.size())
Py_Error(PyExc_Exception,"no file ending");
cEnding.erase(0,pos+1);
App::Document *pcDoc = 0;
if (DocName) {
pcDoc = App::GetApplication().getDocument(DocName);
}
if (!pcDoc) {
pcDoc = App::GetApplication().newDocument("Unnamed");
}
if(cEnding == "stp" || cEnding == "step")
{
// create new document and add Import feature
App::Document *pcDoc = App::GetApplication().newDocument();
App::AbstractFeature *pcFeature = pcDoc->addFeature("ImportStep","Step Import");
pcFeature->setPropertyString (Name,"FileName");
pcFeature->TouchProperty("FileName");
pcDoc->recompute();
Handle(XCAFApp_Application) hApp = XCAFApp_Application::GetApplication();
Handle(TDocStd_Document) hDoc;
hApp->NewDocument(TCollection_ExtendedString("MDTV-CAF"), hDoc);
}else if(cEnding == "igs" || cEnding == "iges")
{
// create new document and add Import feature
App::Document *pcDoc = App::GetApplication().newDocument();
App::AbstractFeature *pcFeature = pcDoc->addFeature("ImportIges","Iges Import");
assert(0);
// pcFeature->GetProperty("FileName").Set(Name);
pcFeature->TouchProperty("FileName");
pcDoc->recompute();
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)Name) != IFSelect_RetDone) {
PyErr_SetString(PyExc_Exception, "cannot read STEP file");
return 0;
}
}else
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");
Py_Error(PyExc_Exception,"unknown file ending");
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)Name) != 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");
Py_Return;
Part::ImportIgesParts(pcDoc,Name);
pcDoc->recompute();
}
}
else {
PyErr_SetString(PyExc_Exception, "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(PyExc_Exception, e->GetMessageString());
return 0;
}
PY_CATCH
Py_Return;
}
/* module functions */
static PyObject *
save(PyObject *self, PyObject *args)
static PyObject * open(PyObject *self, PyObject *args)
{
char* str;
return importer(self, args);
}
if (! PyArg_ParseTuple(args, "s",&str))
static PyObject * exporter(PyObject *self, PyObject *args)
{
PyObject* object;
const char* filename;
if (!PyArg_ParseTuple(args, "Os",&object,&filename))
return NULL;
TopoDS_Shape ResultShape;
BRep_Builder aBuilder;
PY_TRY {
Handle(XCAFApp_Application) hApp = XCAFApp_Application::GetApplication();
Handle(TDocStd_Document) hDoc;
hApp->NewDocument(TCollection_ExtendedString("MDTV-CAF"), hDoc);
Import::ExportOCAF ocaf(hDoc);
BRepTools::Read(ResultShape,(const Standard_CString)str,aBuilder);
Py::List list(object);
for (Py::List::iterator it = list.begin(); it != list.end(); ++it) {
PyObject* item = (*it).ptr();
if (PyObject_TypeCheck(item, &(App::DocumentObjectPy::Type))) {
App::DocumentObject* obj = static_cast<App::DocumentObjectPy*>(item)->getDocumentObjectPtr();
if (obj->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) {
Part::Feature* part = static_cast<Part::Feature*>(obj);
std::vector<App::Color> 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<App::DocumentObjectPy*>(item0.ptr())->getDocumentObjectPtr();
if (obj->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) {
Part::Feature* part = static_cast<Part::Feature*>(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());
}
}
}
}
return new Part::TopoShapePy(ResultShape); /* convert C -> Python */
Base::FileInfo file(filename);
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
makeHeader.SetName(new TCollection_HAsciiString((const Standard_CString)filename));
makeHeader.SetAuthorValue (1, new TCollection_HAsciiString("FreeCAD"));
makeHeader.SetOrganizationValue (1, new TCollection_HAsciiString("FreeCAD"));
makeHeader.SetOriginatingSystem(new TCollection_HAsciiString("FreeCAD"));
makeHeader.SetDescriptionValue(1, new TCollection_HAsciiString("FreeCAD Model"));
writer.Write(filename);
}
else if (file.hasExtension("igs") || file.hasExtension("iges")) {
IGESControl_Controller::Init();
IGESCAFControl_Writer writer;
writer.Transfer(hDoc);
writer.Write(filename);
}
}
catch (Standard_Failure) {
Handle_Standard_Failure e = Standard_Failure::Caught();
PyErr_SetString(PyExc_Exception, e->GetMessageString());
return 0;
}
PY_CATCH
Py_Return;
}
/* registration table */
struct PyMethodDef Import_methods[] = {
{"open", open, 1}, /* method name, C func ptr, always-tuple */
{"save", save, 1},
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."},
{NULL, NULL} /* end of table marker */
};

View File

@ -1,49 +1,55 @@
add_definitions(-DFCAppImport -DFC_DEBUG)
if(MSVC)
add_definitions(-DFCAppImport -DHAVE_ACOSH -DHAVE_ASINH -DHAVE_ATANH)
else(MSVC)
add_definitions(-DHAVE_LIMITS_H -DHAVE_CONFIG_H)
endif(MSVC)
include_directories(
# ${CMAKE_SOURCE_DIR}/src
# ${OPENCV_INCLUDE_DIR}
${OCC_INCLUDE_DIR}
# ${PYTHON_INCLUDE_PATH}
${ZLIB_INCLUDE_DIR}
${XERCES_INCLUDE_DIR})
if(WIN32)
set(Import_LIBS
# ${OPENCV_LIBRARIES}
# -lTKIGES \
# -lTKSTEP \
Part
FreeCADApp)
else(WIN32)
set(Import_LIBS
# -lTKIGES \
# -lTKSTEP \
# -lFreeCADBase \
# -lFreeCADApp \
# -lPart
${CMAKE_CURRENT_BINARY_DIR}
${Boost_INCLUDE_DIRS}
${OCC_INCLUDE_DIR}
${ZLIB_INCLUDE_DIR}
${PYTHON_INCLUDE_PATH}
${XERCESC_INCLUDE_DIR}
)
endif(WIN32)
set(Import_SRCS
AppImport.cpp
AppImportPy.cpp
FeatureImportIges.cpp
FeatureImportIges.h
FeatureImportStep.cpp
FeatureImportStep.h
PreCompiled.cpp
PreCompiled.h
link_directories(${OCC_LIBRARY_DIR})
set(Import_LIBS
Part
${OCC_OCAF_LIBRARIES}
${OCC_OCAF_DEBUG_LIBRARIES}
)
SET(Import_SRCS
AppImport.cpp
AppImportPy.cpp
ImportOCAF.cpp
ImportOCAF.h
PreCompiled.cpp
PreCompiled.h
)
add_library(Import SHARED ${Import_SRCS})
target_link_libraries(Import ${Import_LIBS})
set_target_properties(Import PROPERTIES SUFFIX ".pyd")
if(UNIX)
if(MSVC)
set_target_properties(Import PROPERTIES SUFFIX ".pyd")
set_target_properties(Import PROPERTIES DEBUG_OUTPUT_NAME "Import_d")
set_target_properties(Import PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/Mod/Import)
set_target_properties(Import PROPERTIES PREFIX "../")
# Set special compiler flag to convert a SIGSEV into an exception
set_target_properties(Import PROPERTIES COMPILE_FLAGS "/EHa")
elseif(MINGW)
set_target_properties(Import PROPERTIES SUFFIX ".pyd")
set_target_properties(Import PROPERTIES DEBUG_OUTPUT_NAME "Import_d")
set_target_properties(Import PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/Mod/Import)
set_target_properties(Import PROPERTIES PREFIX "")
else(MSVC)
set_target_properties(Import PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/Mod/Import)
set_target_properties(Import PROPERTIES PREFIX "")
set_target_properties(Import PROPERTIES INSTALL_RPATH ${INSTALL_RPATH})
endif(UNIX)
endif(MSVC)
install(TARGETS Import DESTINATION lib)
INSTALL(TARGETS Import DESTINATION lib)

View File

@ -0,0 +1,548 @@
/***************************************************************************
* Copyright (c) 2013 Werner Mayer <wmayer[at]users.sourceforge.net> *
* *
* 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 <climits>
# include <Standard_Version.hxx>
# include <BRep_Builder.hxx>
# include <Handle_TDocStd_Document.hxx>
# include <Handle_XCAFApp_Application.hxx>
# include <TDocStd_Document.hxx>
# include <XCAFApp_Application.hxx>
# include <XCAFDoc_DocumentTool.hxx>
# include <XCAFDoc_ShapeTool.hxx>
# include <XCAFDoc_ColorTool.hxx>
# include <XCAFDoc_Location.hxx>
# include <TDF_Label.hxx>
# include <TDF_LabelSequence.hxx>
# include <TDF_ChildIterator.hxx>
# include <TDataStd_Name.hxx>
# include <Quantity_Color.hxx>
# include <STEPCAFControl_Reader.hxx>
# include <STEPCAFControl_Writer.hxx>
# include <STEPControl_Writer.hxx>
# include <IGESCAFControl_Reader.hxx>
# include <IGESCAFControl_Writer.hxx>
# include <IGESControl_Controller.hxx>
# include <Interface_Static.hxx>
# include <Transfer_TransientProcess.hxx>
# include <XSControl_WorkSession.hxx>
# include <TopTools_IndexedMapOfShape.hxx>
# include <TopTools_MapOfShape.hxx>
# include <TopExp_Explorer.hxx>
# include <TopoDS_Iterator.hxx>
# include <APIHeaderSection_MakeHeader.hxx>
# include <OSD_Exception.hxx>
#if OCC_VERSION_HEX >= 0x060500
# include <TDataXtd_Shape.hxx>
# else
# include <TDataStd_Shape.hxx>
# endif
#endif
#include "ImportOCAF.h"
#include <Base/Console.h>
#include <App/Application.h>
#include <App/Document.h>
#include <App/DocumentObjectPy.h>
#include <Mod/Part/App/PartFeature.h>
#include <Mod/Part/App/ProgressIndicator.h>
#include <Mod/Part/App/ImportIges.h>
#include <Mod/Part/App/ImportStep.h>
using namespace Import;
ImportOCAF::ImportOCAF(Handle_TDocStd_Document h, App::Document* d, const std::string& name)
: pDoc(h), doc(d), default_name(name)
{
aShapeTool = XCAFDoc_DocumentTool::ShapeTool (pDoc->Main());
aColorTool = XCAFDoc_DocumentTool::ColorTool(pDoc->Main());
}
ImportOCAF::~ImportOCAF()
{
}
void ImportOCAF::loadShapes()
{
myRefShapes.clear();
loadShapes(pDoc->Main(), TopLoc_Location(), default_name, "", false);
}
void ImportOCAF::loadShapes(const TDF_Label& label, const TopLoc_Location& loc, const std::string& defaultname, const std::string& assembly, bool isRef)
{
int hash = 0;
TopoDS_Shape aShape;
if (aShapeTool->GetShape(label,aShape)) {
hash = aShape.HashCode(HashUpper);
}
Handle(TDataStd_Name) name;
std::string part_name = defaultname;
if (label.FindAttribute(TDataStd_Name::GetID(),name)) {
TCollection_ExtendedString extstr = name->Get();
char* str = new char[extstr.LengthOfCString()+1];
extstr.ToUTF8CString(str);
part_name = str;
delete [] str;
if (part_name.empty()) {
part_name = defaultname;
}
else {
bool ws=true;
for (std::string::iterator it = part_name.begin(); it != part_name.end(); ++it) {
if (*it != ' ') {
ws = false;
break;
}
}
if (ws)
part_name = defaultname;
}
}
TopLoc_Location part_loc = loc;
Handle(XCAFDoc_Location) hLoc;
if (label.FindAttribute(XCAFDoc_Location::GetID(), hLoc)) {
if (isRef)
part_loc = part_loc * hLoc->Get();
else
part_loc = hLoc->Get();
}
#ifdef FC_DEBUG
Base::Console().Message("H:%d, N:%s, T:%d, A:%d, S:%d, C:%d, SS:%d, F:%d, R:%d, C:%d, SS:%d\n",
hash,
part_name.c_str(),
aShapeTool->IsTopLevel(label),
aShapeTool->IsAssembly(label),
aShapeTool->IsShape(label),
aShapeTool->IsCompound(label),
aShapeTool->IsSimpleShape(label),
aShapeTool->IsFree(label),
aShapeTool->IsReference(label),
aShapeTool->IsComponent(label),
aShapeTool->IsSubShape(label)
);
#endif
std::string asm_name = assembly;
if (aShapeTool->IsAssembly(label)) {
asm_name = part_name;
}
TDF_Label ref;
if (aShapeTool->IsReference(label) && aShapeTool->GetReferredShape(label, ref)) {
loadShapes(ref, part_loc, part_name, asm_name, true);
}
if (isRef || myRefShapes.find(hash) == myRefShapes.end()) {
TopoDS_Shape aShape;
if (isRef && aShapeTool->GetShape(label, aShape))
myRefShapes.insert(aShape.HashCode(HashUpper));
if (aShapeTool->IsSimpleShape(label) && (isRef || aShapeTool->IsFree(label))) {
if (!asm_name.empty())
part_name = asm_name;
if (isRef)
createShape(label, loc, part_name);
else
createShape(label, part_loc, part_name);
}
else {
for (TDF_ChildIterator it(label); it.More(); it.Next()) {
loadShapes(it.Value(), part_loc, part_name, asm_name, isRef);
}
}
}
}
void ImportOCAF::createShape(const TDF_Label& label, const TopLoc_Location& loc, const std::string& name)
{
const TopoDS_Shape& aShape = aShapeTool->GetShape(label);
if (!aShape.IsNull() && aShape.ShapeType() == TopAbs_COMPOUND) {
TopExp_Explorer xp;
int ctSolids = 0, ctShells = 0;
for (xp.Init(aShape, TopAbs_SOLID); xp.More(); xp.Next(), ctSolids++)
createShape(xp.Current(), loc, name);
for (xp.Init(aShape, TopAbs_SHELL, TopAbs_SOLID); xp.More(); xp.Next(), ctShells++)
createShape(xp.Current(), loc, name);
if (ctSolids > 0 || ctShells > 0)
return;
}
createShape(aShape, loc, name);
}
void ImportOCAF::createShape(const TopoDS_Shape& aShape, const TopLoc_Location& loc, const std::string& name)
{
Part::Feature* part = static_cast<Part::Feature*>(doc->addObject("Part::Feature"));
if (!loc.IsIdentity())
part->Shape.setValue(aShape.Moved(loc));
else
part->Shape.setValue(aShape);
part->Label.setValue(name);
Quantity_Color aColor;
App::Color color(0.8f,0.8f,0.8f);
if (aColorTool->GetColor(aShape, XCAFDoc_ColorGen, aColor) ||
aColorTool->GetColor(aShape, XCAFDoc_ColorSurf, aColor) ||
aColorTool->GetColor(aShape, XCAFDoc_ColorCurv, aColor)) {
color.r = aColor.Red();
color.g = aColor.Green();
color.b = aColor.Blue();
std::vector<App::Color> colors;
colors.push_back(color);
applyColors(part, colors);
#if 0//TODO
Gui::ViewProvider* vp = Gui::Application::Instance->getViewProvider(part);
if (vp && vp->isDerivedFrom(PartGui::ViewProviderPart::getClassTypeId())) {
color.r = aColor.Red();
color.g = aColor.Green();
color.b = aColor.Blue();
static_cast<PartGui::ViewProviderPart*>(vp)->ShapeColor.setValue(color);
}
#endif
}
TopTools_IndexedMapOfShape faces;
TopExp_Explorer xp(aShape,TopAbs_FACE);
while (xp.More()) {
faces.Add(xp.Current());
xp.Next();
}
bool found_face_color = false;
std::vector<App::Color> faceColors;
faceColors.resize(faces.Extent(), color);
xp.Init(aShape,TopAbs_FACE);
while (xp.More()) {
if (aColorTool->GetColor(xp.Current(), XCAFDoc_ColorGen, aColor) ||
aColorTool->GetColor(xp.Current(), XCAFDoc_ColorSurf, aColor) ||
aColorTool->GetColor(xp.Current(), XCAFDoc_ColorCurv, aColor)) {
int index = faces.FindIndex(xp.Current());
color.r = aColor.Red();
color.g = aColor.Green();
color.b = aColor.Blue();
faceColors[index-1] = color;
found_face_color = true;
}
xp.Next();
}
if (found_face_color) {
applyColors(part, faceColors);
#if 0//TODO
Gui::ViewProvider* vp = Gui::Application::Instance->getViewProvider(part);
if (vp && vp->isDerivedFrom(PartGui::ViewProviderPartExt::getClassTypeId())) {
static_cast<PartGui::ViewProviderPartExt*>(vp)->DiffuseColor.setValues(faceColors);
}
#endif
}
}
// ----------------------------------------------------------------------------
ExportOCAF::ExportOCAF(Handle_TDocStd_Document h)
: pDoc(h)
{
aShapeTool = XCAFDoc_DocumentTool::ShapeTool(pDoc->Main());
aColorTool = XCAFDoc_DocumentTool::ColorTool(pDoc->Main());
rootLabel = TDF_TagSource::NewChild(pDoc->Main());
}
void ExportOCAF::saveShape(Part::Feature* part, const std::vector<App::Color>& colors)
{
const TopoDS_Shape& shape = part->Shape.getValue();
// Add shape and name
//TDF_Label shapeLabel = hShapeTool->AddShape(shape, Standard_False);
TDF_Label shapeLabel= TDF_TagSource::NewChild(rootLabel);
#if OCC_VERSION_HEX >= 0x060500
TDataXtd_Shape::Set(shapeLabel, shape);
#else
TDataStd_Shape::Set(shapeLabel, shape);
#endif
TDataStd_Name::Set(shapeLabel, TCollection_ExtendedString(part->Label.getValue(), 1));
// Add color information
Quantity_Color col;
std::set<int> face_index;
TopTools_IndexedMapOfShape faces;
TopExp_Explorer xp(shape,TopAbs_FACE);
while (xp.More()) {
face_index.insert(faces.Add(xp.Current()));
xp.Next();
}
// define color per face?
if (colors.size() == face_index.size()) {
xp.Init(shape,TopAbs_FACE);
while (xp.More()) {
int index = faces.FindIndex(xp.Current());
if (face_index.find(index) != face_index.end()) {
face_index.erase(index);
TDF_Label faceLabel= TDF_TagSource::NewChild(shapeLabel);
#if OCC_VERSION_HEX >= 0x060500
TDataXtd_Shape::Set(faceLabel, xp.Current());
#else
TDataStd_Shape::Set(faceLabel, xp.Current());
#endif
const App::Color& color = colors[index-1];
Quantity_Parameter mat[3];
mat[0] = color.r;
mat[1] = color.g;
mat[2] = color.b;
col.SetValues(mat[0],mat[1],mat[2],Quantity_TOC_RGB);
aColorTool->SetColor(faceLabel, col, XCAFDoc_ColorSurf);
}
xp.Next();
}
}
else if (!colors.empty()) {
App::Color color = colors.front();
Quantity_Parameter mat[3];
mat[0] = color.r;
mat[1] = color.g;
mat[2] = color.b;
col.SetValues(mat[0],mat[1],mat[2],Quantity_TOC_RGB);
aColorTool->SetColor(shapeLabel, col, XCAFDoc_ColorGen);
}
}
// ----------------------------------------------------------------------------
ImportXCAF::ImportXCAF(Handle_TDocStd_Document h, App::Document* d, const std::string& name)
: hdoc(h), doc(d), default_name(name)
{
aShapeTool = XCAFDoc_DocumentTool::ShapeTool (hdoc->Main());
hColors = XCAFDoc_DocumentTool::ColorTool(hdoc->Main());
}
ImportXCAF::~ImportXCAF()
{
}
void ImportXCAF::loadShapes()
{
// collect sequence of labels to display
TDF_LabelSequence shapeLabels, colorLabels;
aShapeTool->GetFreeShapes (shapeLabels);
hColors->GetColors(colorLabels);
// set presentations and show
for (Standard_Integer i=1; i <= shapeLabels.Length(); i++ ) {
// get the shapes and attributes
const TDF_Label& label = shapeLabels.Value(i);
loadShapes(label);
}
std::map<Standard_Integer, TopoDS_Shape>::iterator it;
// go through solids
for (it = mySolids.begin(); it != mySolids.end(); ++it) {
createShape(it->second, true, true);
}
// go through shells
for (it = myShells.begin(); it != myShells.end(); ++it) {
createShape(it->second, true, true);
}
// go through compounds
for (it = myCompds.begin(); it != myCompds.end(); ++it) {
createShape(it->second, true, true);
}
// do the rest
if (!myShapes.empty()) {
BRep_Builder builder;
TopoDS_Compound comp;
builder.MakeCompound(comp);
for (it = myShapes.begin(); it != myShapes.end(); ++it) {
builder.Add(comp, it->second);
}
createShape(comp, true, false);
}
}
void ImportXCAF::createShape(const TopoDS_Shape& shape, bool perface, bool setname) const
{
Part::Feature* part;
part = static_cast<Part::Feature*>(doc->addObject("Part::Feature", default_name.c_str()));
part->Shape.setValue(shape);
std::map<Standard_Integer, Quantity_Color>::const_iterator jt;
jt = myColorMap.find(shape.HashCode(INT_MAX));
App::Color partColor(0.8f,0.8f,0.8f);
#if 0//TODO
Gui::ViewProvider* vp = Gui::Application::Instance->getViewProvider(part);
if (vp && vp->isDerivedFrom(PartGui::ViewProviderPart::getClassTypeId())) {
if (jt != myColorMap.end()) {
App::Color color;
color.r = jt->second.Red();
color.g = jt->second.Green();
color.b = jt->second.Blue();
static_cast<PartGui::ViewProviderPart*>(vp)->ShapeColor.setValue(color);
}
partColor = static_cast<PartGui::ViewProviderPart*>(vp)->ShapeColor.getValue();
}
#endif
// set label name if defined
if (setname && !myNameMap.empty()) {
std::map<Standard_Integer, std::string>::const_iterator jt;
jt = myNameMap.find(shape.HashCode(INT_MAX));
if (jt != myNameMap.end()) {
part->Label.setValue(jt->second);
}
}
// check for colors per face
if (perface && !myColorMap.empty()) {
TopTools_IndexedMapOfShape faces;
TopExp_Explorer xp(shape,TopAbs_FACE);
while (xp.More()) {
faces.Add(xp.Current());
xp.Next();
}
bool found_face_color = false;
std::vector<App::Color> faceColors;
faceColors.resize(faces.Extent(), partColor);
xp.Init(shape,TopAbs_FACE);
while (xp.More()) {
jt = myColorMap.find(xp.Current().HashCode(INT_MAX));
if (jt != myColorMap.end()) {
int index = faces.FindIndex(xp.Current());
App::Color color;
color.r = jt->second.Red();
color.g = jt->second.Green();
color.b = jt->second.Blue();
faceColors[index-1] = color;
found_face_color = true;
}
xp.Next();
}
if (found_face_color) {
#if 0//TODO
Gui::ViewProvider* vp = Gui::Application::Instance->getViewProvider(part);
if (vp && vp->isDerivedFrom(PartGui::ViewProviderPartExt::getClassTypeId())) {
static_cast<PartGui::ViewProviderPartExt*>(vp)->DiffuseColor.setValues(faceColors);
}
#endif
}
}
}
void ImportXCAF::loadShapes(const TDF_Label& label)
{
TopoDS_Shape aShape;
if (aShapeTool->GetShape(label,aShape)) {
//if (aShapeTool->IsReference(label)) {
// TDF_Label reflabel;
// if (aShapeTool->GetReferredShape(label, reflabel)) {
// loadShapes(reflabel);
// }
//}
if (aShapeTool->IsTopLevel(label)) {
int ctSolids = 0, ctShells = 0, ctComps = 0;
// add the shapes
TopExp_Explorer xp;
for (xp.Init(aShape, TopAbs_SOLID); xp.More(); xp.Next(), ctSolids++)
this->mySolids[xp.Current().HashCode(INT_MAX)] = (xp.Current());
for (xp.Init(aShape, TopAbs_SHELL, TopAbs_SOLID); xp.More(); xp.Next(), ctShells++)
this->myShells[xp.Current().HashCode(INT_MAX)] = (xp.Current());
// if no solids and no shells were found then go for compounds
if (ctSolids == 0 && ctShells == 0) {
for (xp.Init(aShape, TopAbs_COMPOUND); xp.More(); xp.Next(), ctComps++)
this->myCompds[xp.Current().HashCode(INT_MAX)] = (xp.Current());
}
if (ctComps == 0) {
for (xp.Init(aShape, TopAbs_FACE, TopAbs_SHELL); xp.More(); xp.Next())
this->myShapes[xp.Current().HashCode(INT_MAX)] = (xp.Current());
for (xp.Init(aShape, TopAbs_WIRE, TopAbs_FACE); xp.More(); xp.Next())
this->myShapes[xp.Current().HashCode(INT_MAX)] = (xp.Current());
for (xp.Init(aShape, TopAbs_EDGE, TopAbs_WIRE); xp.More(); xp.Next())
this->myShapes[xp.Current().HashCode(INT_MAX)] = (xp.Current());
for (xp.Init(aShape, TopAbs_VERTEX, TopAbs_EDGE); xp.More(); xp.Next())
this->myShapes[xp.Current().HashCode(INT_MAX)] = (xp.Current());
}
}
// getting color
Quantity_Color col;
if (hColors->GetColor(label, XCAFDoc_ColorGen, col) ||
hColors->GetColor(label, XCAFDoc_ColorSurf, col) ||
hColors->GetColor(label, XCAFDoc_ColorCurv, col)) {
// add defined color
myColorMap[aShape.HashCode(INT_MAX)] = col;
}
else {
// http://www.opencascade.org/org/forum/thread_17107/
TopoDS_Iterator it;
for (it.Initialize(aShape);it.More(); it.Next()) {
if (hColors->GetColor(it.Value(), XCAFDoc_ColorGen, col) ||
hColors->GetColor(it.Value(), XCAFDoc_ColorSurf, col) ||
hColors->GetColor(it.Value(), XCAFDoc_ColorCurv, col)) {
// add defined color
myColorMap[it.Value().HashCode(INT_MAX)] = col;
}
}
}
// getting names
Handle(TDataStd_Name) name;
if (label.FindAttribute(TDataStd_Name::GetID(),name)) {
TCollection_ExtendedString extstr = name->Get();
char* str = new char[extstr.LengthOfCString()+1];
extstr.ToUTF8CString(str);
std::string label(str);
if (!label.empty())
myNameMap[aShape.HashCode(INT_MAX)] = label;
delete [] str;
}
#if 0
// http://www.opencascade.org/org/forum/thread_15174/
if (aShapeTool->IsAssembly(label)) {
TDF_LabelSequence shapeLabels;
aShapeTool->GetComponents(label, shapeLabels);
Standard_Integer nbShapes = shapeLabels.Length();
for (Standard_Integer i = 1; i <= nbShapes; i++) {
loadShapes(shapeLabels.Value(i));
}
}
#endif
if (label.HasChild()) {
TDF_ChildIterator it;
for (it.Initialize(label); it.More(); it.Next()) {
loadShapes(it.Value());
}
}
}
}

View File

@ -0,0 +1,117 @@
/***************************************************************************
* Copyright (c) 2013 Werner Mayer <wmayer[at]users.sourceforge.net> *
* *
* 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 IMPORT_IMPORTOCAF_H
#define IMPORT_IMPORTOCAF_H
#include <Handle_TDocStd_Document.hxx>
#include <Handle_XCAFDoc_ColorTool.hxx>
#include <Handle_XCAFDoc_ShapeTool.hxx>
#include <Quantity_Color.hxx>
#include <TopoDS_Shape.hxx>
#include <climits>
#include <string>
#include <set>
#include <map>
#include <vector>
#include <App/Material.h>
class TDF_Label;
class TopLoc_Location;
namespace App {
class Document;
class DocumentObject;
}
namespace Part {
class Feature;
}
namespace Import {
class ImportExport ImportOCAF
{
public:
ImportOCAF(Handle_TDocStd_Document h, App::Document* d, const std::string& name);
virtual ~ImportOCAF();
void loadShapes();
private:
void loadShapes(const TDF_Label& label, const TopLoc_Location&, const std::string& partname, const std::string& assembly, bool isRef);
void createShape(const TDF_Label& label, const TopLoc_Location&, const std::string&);
void createShape(const TopoDS_Shape& label, const TopLoc_Location&, const std::string&);
virtual void applyColors(Part::Feature*, const std::vector<App::Color>&){}
private:
Handle_TDocStd_Document pDoc;
App::Document* doc;
Handle_XCAFDoc_ShapeTool aShapeTool;
Handle_XCAFDoc_ColorTool aColorTool;
std::string default_name;
std::set<int> myRefShapes;
static const int HashUpper = INT_MAX;
};
class ImportExport ExportOCAF
{
public:
ExportOCAF(Handle_TDocStd_Document h);
void saveShape(Part::Feature* part, const std::vector<App::Color>&);
private:
Handle_TDocStd_Document pDoc;
Handle_XCAFDoc_ShapeTool aShapeTool;
Handle_XCAFDoc_ColorTool aColorTool;
TDF_Label rootLabel;
};
class ImportXCAF
{
public:
ImportXCAF(Handle_TDocStd_Document h, App::Document* d, const std::string& name);
virtual ~ImportXCAF();
void loadShapes();
private:
void createShape(const TopoDS_Shape& shape, bool perface=false, bool setname=false) const;
void loadShapes(const TDF_Label& label);
virtual void applyColors(Part::Feature*, const std::vector<App::Color>&){}
private:
Handle_TDocStd_Document hdoc;
App::Document* doc;
Handle_XCAFDoc_ShapeTool aShapeTool;
Handle_XCAFDoc_ColorTool hColors;
std::string default_name;
std::map<Standard_Integer, TopoDS_Shape> mySolids;
std::map<Standard_Integer, TopoDS_Shape> myShells;
std::map<Standard_Integer, TopoDS_Shape> myCompds;
std::map<Standard_Integer, TopoDS_Shape> myShapes;
std::map<Standard_Integer, Quantity_Color> myColorMap;
std::map<Standard_Integer, std::string> myNameMap;
};
}
#endif //IMPORT_IMPORTOCAF_H

View File

@ -25,25 +25,32 @@
#define __PRECOMPILED__
#include <FCConfig.h>
#ifdef _PreComp_
/// here get the warnings of to long specifieres disabled (needet for VC6)
#ifdef _MSC_VER
# pragma warning( disable : 4251 )
# pragma warning( disable : 4503 )
# pragma warning( disable : 4786 ) // specifier longer then 255 chars
#endif
// Importing of App classes
#ifdef FC_OS_WIN32
# define ImportExport __declspec(dllexport)
# define PartExport __declspec(dllimport)
# define AppPartExport __declspec(dllimport)
#else // for Linux
# define ImportExport
# define PartExport
# define AppPartExport
#endif
/// here get the warnings of to long specifieres disabled (needet for VC6)
#ifdef _MSC_VER
# pragma warning( disable : 4251 )
# pragma warning( disable : 4503 )
# pragma warning( disable : 4786 ) // specifier longer then 255 chars
#endif
#ifdef _PreComp_
// Python
#include <Python.h>
// standard
#include <list>
#include <iostream>
@ -60,188 +67,8 @@
// OpenCasCade =====================================================================================
// Base
#include <Standard_Failure.hxx>
#include <Standard_GUID.hxx>
#include <Standard_AbortiveTransaction.hxx>
#include <Standard_Address.hxx>
#include <Standard_AncestorIterator.hxx>
#include <Standard_BasicMap.hxx>
#include <Standard_BasicMapIterator.hxx>
#include <Standard_Boolean.hxx>
#include <Standard_Byte.hxx>
#include <Standard_Character.hxx>
#include <Standard_ConstructionError.hxx>
#include <Standard_Container.hxx>
#include <Standard_CString.hxx>
#include <Standard_ctype.hxx>
#include <Standard_DBHandle.hxx>
#include <Standard_DefineHandle.hxx>
#include <Standard_DimensionError.hxx>
#include <Standard_DimensionMismatch.hxx>
#include <Standard_DivideByZero.hxx>
#include <Standard_DomainError.hxx>
#include <Standard_ErrorHandler.hxx>
#include <Standard_ExtCharacter.hxx>
#include <Standard_ExtString.hxx>
#include <Standard_Failure.hxx>
#include <Standard_ForMapOfTypes.hxx>
#include <Standard_GUID.hxx>
#include <Standard_ImmutableObject.hxx>
#include <Standard_Integer.hxx>
#include <Standard_InternalType.hxx>
#include <Standard_IStream.hxx>
#include <Standard_KindOfType.hxx>
#include <Standard_LicenseError.hxx>
#include <Standard_LicenseNotFound.hxx>
#include <Standard_Macro.hxx>
#include <Standard_MapOfTypes.hxx>
#include <Standard_math.hxx>
#include <Standard_MultiplyDefined.hxx>
#include <Standard_MyMapOfStringsHasher.hxx>
#include <Standard_MyMapOfTypes.hxx>
#include <Standard_NegativeValue.hxx>
#include <Standard_NoMoreObject.hxx>
#include <Standard_NoSuchObject.hxx>
#include <Standard_NotImplemented.hxx>
#include <Standard_NullObject.hxx>
#include <Standard_NullValue.hxx>
#include <Standard_NumericError.hxx>
#include <Standard_OId.hxx>
#include <Standard_OStream.hxx>
#include <Standard_OutOfMemory.hxx>
#include <Standard_OutOfRange.hxx>
#include <Standard_Overflow.hxx>
#include <Standard_Persistent.hxx>
#include <Standard_Persistent_proto.hxx>
#include <Standard_PForMapOfTypes.hxx>
#include <Standard_PrimitiveTypes.hxx>
#include <Standard_ProgramError.hxx>
#include <Standard_RangeError.hxx>
#include <Standard_Real.hxx>
#include <Standard_ShortReal.hxx>
#include <Standard_SStream.hxx>
#include <Standard_Static.hxx>
#include <Standard_Storable.hxx>
#include <Standard_Stream.hxx>
#include <Standard_String.hxx>
#include <Standard_theForMapOfTypes.hxx>
#include <Standard_TooManyUsers.hxx>
#include <Standard_Transient.hxx>
#include <Standard_Transient_proto.hxx>
#include <Standard_Type.hxx>
#include <Standard_TypeDef.hxx>
#include <Standard_TypeMismatch.hxx>
#include <Standard_Underflow.hxx>
#include <Standard_UUID.hxx>
#include <Standard_WayOfLife.hxx>
#include <Quantity_Date.hxx>
#include <TCollection_ExtendedString.hxx>
#include <TCollection_AsciiString.hxx>
#include <TColStd_SequenceOfExtendedString.hxx>
// OCAF
#include <TDF_Label.hxx>
#include <TDF_ChildIterator.hxx>
#include <TDF_Tool.hxx>
#include <TDF_ListIteratorOfAttributeList.hxx>
#include <TDocStd_Application.hxx>
#include <TDataStd_Real.hxx>
#include <TDataStd_Integer.hxx>
#include <TDataStd_Name.hxx>
#include <TDataStd_RealArray.hxx>
#include <TDataStd_IntegerArray.hxx>
#include <TDataStd_Comment.hxx>
#include <BRepBuilderAPI.hxx>
#include <BRepTools.hxx>
#include <Standard_DefineHandle.hxx>
#include <DsgPrs_LengthPresentation.hxx>
#include <GCE2d_MakeSegment.hxx>
#include <GCPnts_TangentialDeflection.hxx>
#include <Geom_Axis2Placement.hxx>
#include <Geom_CartesianPoint.hxx>
#include <Geom_Line.hxx>
#include <Geom_Surface.hxx>
#include <Geom2d_BezierCurve.hxx>
#include <Geom2d_BSplineCurve.hxx>
#include <Geom2d_Curve.hxx>
#include <Geom2d_TrimmedCurve.hxx>
#include <Geom2dAdaptor_Curve.hxx>
#include <GeomAbs_CurveType.hxx>
#include <GeomAdaptor_Curve.hxx>
#include <GeomTools_Curve2dSet.hxx>
#include <gp_Ax2d.hxx>
#include <gp_Circ2d.hxx>
#include <gp_Dir2d.hxx>
#include <gp_Lin2d.hxx>
#include <gp_Pnt2d.hxx>
#include <gp_Vec.hxx>
#include <gp_Vec2d.hxx>
#include <MMgt_TShared.hxx>
#include <OSD_Environment.hxx>
#include <Precision.hxx>
#include <Quantity_Factor.hxx>
#include <Quantity_Length.hxx>
#include <Quantity_NameOfColor.hxx>
#include <Quantity_PhysicalQuantity.hxx>
#include <Quantity_PlaneAngle.hxx>
#include <Quantity_TypeOfColor.hxx>
#include <ShapeSchema.hxx>
#include <Standard_Boolean.hxx>
#include <Standard_CString.hxx>
#include <Standard_ErrorHandler.hxx>
#include <Standard_Integer.hxx>
#include <Standard_IStream.hxx>
#include <Standard_Macro.hxx>
#include <Standard_NotImplemented.hxx>
#include <Standard_OStream.hxx>
#include <Standard_Real.hxx>
#include <TCollection_AsciiString.hxx>
#include <TColgp_Array1OfPnt2d.hxx>
#include <TColgp_HArray1OfPnt2d.hxx>
#include <TCollection_AsciiString.hxx>
#include <TColStd_HSequenceOfTransient.hxx>
#include <TColStd_MapIteratorOfMapOfTransient.hxx>
#include <TColStd_MapOfTransient.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Compound.hxx>
#include <TopoDS_ListIteratorOfListOfShape.hxx>
#include <TopoDS_Shape.hxx>
#include <TopoDS_Solid.hxx>
#include <TopoDS_Vertex.hxx>
#include <TopExp.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
#include <TopTools_HSequenceOfShape.hxx>
#include <UnitsAPI.hxx>
#include <BRepPrimAPI_MakeBox.hxx>
#include <BRepPrimAPI_MakeCylinder.hxx>
// OCAF
#include <TDocStd_Document.hxx>
#include <TDF_Label.hxx>
#include <TDF_Reference.hxx>
#include <TDF_ChildIterator.hxx>
#include <TNaming_NamedShape.hxx>
#include <TNaming_Builder.hxx>
#include <TDataStd_Real.hxx>
#include <TFunction_Logbook.hxx>
#include <TDataStd_Name.hxx>
#include <TFunction_DriverTable.hxx>
#include <TFunction_Function.hxx>
#include <TDataStd_Integer.hxx>
// IO
#include <IGESControl_Controller.hxx>
#include <IGESControl_Writer.hxx>
#include <IGESControl_Reader.hxx>
#include <STEPControl_Writer.hxx>
#include <STEPControl_Reader.hxx>
#include "OpenCascadeAll.h"
#endif //_PreComp_
#endif

View File

@ -1,5 +1,5 @@
#add_subdirectory(App)
add_subdirectory(App)
if(FREECAD_BUILD_GUI)
add_subdirectory(Gui)
endif(FREECAD_BUILD_GUI)

View File

@ -77,411 +77,26 @@
#include <Mod/Part/App/ProgressIndicator.h>
#include <Mod/Part/App/ImportIges.h>
#include <Mod/Part/App/ImportStep.h>
#include <Mod/Import/App/ImportOCAF.h>
class ImportOCAF
class ImportOCAFExt : public Import::ImportOCAF
{
public:
ImportOCAF(Handle_TDocStd_Document h, App::Document* d, const std::string& name)
: pDoc(h), doc(d), default_name(name)
ImportOCAFExt(Handle_TDocStd_Document h, App::Document* d, const std::string& name)
: ImportOCAF(h, d, name)
{
aShapeTool = XCAFDoc_DocumentTool::ShapeTool (pDoc->Main());
aColorTool = XCAFDoc_DocumentTool::ColorTool(pDoc->Main());
}
void loadShapes();
private:
void loadShapes(const TDF_Label& label, const TopLoc_Location&, const std::string& partname, bool isRef);
void createShape(const TDF_Label& label, const TopLoc_Location&, const std::string&);
void createShape(const TopoDS_Shape& label, const TopLoc_Location&, const std::string&);
private:
Handle_TDocStd_Document pDoc;
App::Document* doc;
Handle_XCAFDoc_ShapeTool aShapeTool;
Handle_XCAFDoc_ColorTool aColorTool;
std::string default_name;
std::set<int> myRefShapes;
static const int HashUpper = INT_MAX;
};
void ImportOCAF::loadShapes()
{
myRefShapes.clear();
loadShapes(pDoc->Main(), TopLoc_Location(), default_name, false);
}
void ImportOCAF::loadShapes(const TDF_Label& label, const TopLoc_Location& loc, const std::string& defaultname, bool isRef)
{
int hash = 0;
TopoDS_Shape aShape;
if (aShapeTool->GetShape(label,aShape)) {
hash = aShape.HashCode(HashUpper);
}
Handle(TDataStd_Name) name;
std::string part_name = defaultname;
if (label.FindAttribute(TDataStd_Name::GetID(),name)) {
TCollection_ExtendedString extstr = name->Get();
char* str = new char[extstr.LengthOfCString()+1];
extstr.ToUTF8CString(str);
part_name = str;
delete [] str;
if (part_name.empty()) {
part_name = defaultname;
}
else {
bool ws=true;
for (std::string::iterator it = part_name.begin(); it != part_name.end(); ++it) {
if (*it != ' ') {
ws = false;
break;
}
}
if (ws)
part_name = defaultname;
}
}
TopLoc_Location part_loc = loc;
Handle(XCAFDoc_Location) hLoc;
if (label.FindAttribute(XCAFDoc_Location::GetID(), hLoc)) {
if (isRef)
part_loc = part_loc * hLoc->Get();
else
part_loc = hLoc->Get();
}
#ifdef FC_DEBUG
Base::Console().Message("H:%d, N:%s, T:%d, A:%d, S:%d, C:%d, SS:%d, F:%d, R:%d, C:%d, SS:%d\n",
hash,
part_name.c_str(),
aShapeTool->IsTopLevel(label),
aShapeTool->IsAssembly(label),
aShapeTool->IsShape(label),
aShapeTool->IsCompound(label),
aShapeTool->IsSimpleShape(label),
aShapeTool->IsFree(label),
aShapeTool->IsReference(label),
aShapeTool->IsComponent(label),
aShapeTool->IsSubShape(label)
);
#endif
TDF_Label ref;
if (aShapeTool->IsReference(label) && aShapeTool->GetReferredShape(label, ref)) {
loadShapes(ref, part_loc, part_name, true);
}
if (isRef || myRefShapes.find(hash) == myRefShapes.end()) {
TopoDS_Shape aShape;
if (isRef && aShapeTool->GetShape(label, aShape))
myRefShapes.insert(aShape.HashCode(HashUpper));
if (aShapeTool->IsSimpleShape(label) && (isRef || aShapeTool->IsFree(label))) {
if (isRef)
createShape(label, loc, part_name);
else
createShape(label, part_loc, part_name);
}
else {
for (TDF_ChildIterator it(label); it.More(); it.Next()) {
loadShapes(it.Value(), part_loc, part_name, isRef);
}
}
}
}
void ImportOCAF::createShape(const TDF_Label& label, const TopLoc_Location& loc, const std::string& name)
{
const TopoDS_Shape& aShape = aShapeTool->GetShape(label);
if (!aShape.IsNull() && aShape.ShapeType() == TopAbs_COMPOUND) {
TopExp_Explorer xp;
int ctSolids = 0, ctShells = 0;
for (xp.Init(aShape, TopAbs_SOLID); xp.More(); xp.Next(), ctSolids++)
createShape(xp.Current(), loc, name);
for (xp.Init(aShape, TopAbs_SHELL, TopAbs_SOLID); xp.More(); xp.Next(), ctShells++)
createShape(xp.Current(), loc, name);
if (ctSolids > 0 || ctShells > 0)
return;
}
createShape(aShape, loc, name);
}
void ImportOCAF::createShape(const TopoDS_Shape& aShape, const TopLoc_Location& loc, const std::string& name)
{
Part::Feature* part = static_cast<Part::Feature*>(doc->addObject("Part::Feature"));
if (!loc.IsIdentity())
part->Shape.setValue(aShape.Moved(loc));
else
part->Shape.setValue(aShape);
part->Label.setValue(name);
Quantity_Color aColor;
App::Color color(0.8f,0.8f,0.8f);
if (aColorTool->GetColor(aShape, XCAFDoc_ColorGen, aColor) ||
aColorTool->GetColor(aShape, XCAFDoc_ColorSurf, aColor) ||
aColorTool->GetColor(aShape, XCAFDoc_ColorCurv, aColor)) {
Gui::ViewProvider* vp = Gui::Application::Instance->getViewProvider(part);
if (vp && vp->isDerivedFrom(PartGui::ViewProviderPart::getClassTypeId())) {
color.r = aColor.Red();
color.g = aColor.Green();
color.b = aColor.Blue();
static_cast<PartGui::ViewProviderPart*>(vp)->ShapeColor.setValue(color);
}
}
TopTools_IndexedMapOfShape faces;
TopExp_Explorer xp(aShape,TopAbs_FACE);
while (xp.More()) {
faces.Add(xp.Current());
xp.Next();
}
bool found_face_color = false;
std::vector<App::Color> faceColors;
faceColors.resize(faces.Extent(), color);
xp.Init(aShape,TopAbs_FACE);
while (xp.More()) {
if (aColorTool->GetColor(xp.Current(), XCAFDoc_ColorGen, aColor) ||
aColorTool->GetColor(xp.Current(), XCAFDoc_ColorSurf, aColor) ||
aColorTool->GetColor(xp.Current(), XCAFDoc_ColorCurv, aColor)) {
int index = faces.FindIndex(xp.Current());
color.r = aColor.Red();
color.g = aColor.Green();
color.b = aColor.Blue();
faceColors[index-1] = color;
found_face_color = true;
}
xp.Next();
}
if (found_face_color) {
void applyColors(Part::Feature* part, const std::vector<App::Color>& colors)
{
Gui::ViewProvider* vp = Gui::Application::Instance->getViewProvider(part);
if (vp && vp->isDerivedFrom(PartGui::ViewProviderPartExt::getClassTypeId())) {
static_cast<PartGui::ViewProviderPartExt*>(vp)->DiffuseColor.setValues(faceColors);
static_cast<PartGui::ViewProviderPartExt*>(vp)->DiffuseColor.setValues(colors);
}
}
}
class ImportXCAF
{
public:
ImportXCAF(Handle_TDocStd_Document h, App::Document* d, const std::string& name)
: hdoc(h), doc(d), default_name(name)
{
aShapeTool = XCAFDoc_DocumentTool::ShapeTool (hdoc->Main());
hColors = XCAFDoc_DocumentTool::ColorTool(hdoc->Main());
}
void loadShapes()
{
// collect sequence of labels to display
TDF_LabelSequence shapeLabels, colorLabels;
aShapeTool->GetFreeShapes (shapeLabels);
hColors->GetColors(colorLabels);
// set presentations and show
for (Standard_Integer i=1; i <= shapeLabels.Length(); i++ ) {
// get the shapes and attributes
const TDF_Label& label = shapeLabels.Value(i);
loadShapes(label);
}
std::map<Standard_Integer, TopoDS_Shape>::iterator it;
// go through solids
for (it = mySolids.begin(); it != mySolids.end(); ++it) {
createShape(it->second, true, true);
}
// go through shells
for (it = myShells.begin(); it != myShells.end(); ++it) {
createShape(it->second, true, true);
}
// go through compounds
for (it = myCompds.begin(); it != myCompds.end(); ++it) {
createShape(it->second, true, true);
}
// do the rest
if (!myShapes.empty()) {
BRep_Builder builder;
TopoDS_Compound comp;
builder.MakeCompound(comp);
for (it = myShapes.begin(); it != myShapes.end(); ++it) {
builder.Add(comp, it->second);
}
createShape(comp, true, false);
}
}
private:
void createShape(const TopoDS_Shape& shape, bool perface=false, bool setname=false) const
{
Part::Feature* part;
part = static_cast<Part::Feature*>(doc->addObject("Part::Feature", default_name.c_str()));
part->Shape.setValue(shape);
std::map<Standard_Integer, Quantity_Color>::const_iterator jt;
jt = myColorMap.find(shape.HashCode(INT_MAX));
App::Color partColor(0.8f,0.8f,0.8f);
Gui::ViewProvider* vp = Gui::Application::Instance->getViewProvider(part);
if (vp && vp->isDerivedFrom(PartGui::ViewProviderPart::getClassTypeId())) {
if (jt != myColorMap.end()) {
App::Color color;
color.r = jt->second.Red();
color.g = jt->second.Green();
color.b = jt->second.Blue();
static_cast<PartGui::ViewProviderPart*>(vp)->ShapeColor.setValue(color);
}
partColor = static_cast<PartGui::ViewProviderPart*>(vp)->ShapeColor.getValue();
}
// set label name if defined
if (setname && !myNameMap.empty()) {
std::map<Standard_Integer, std::string>::const_iterator jt;
jt = myNameMap.find(shape.HashCode(INT_MAX));
if (jt != myNameMap.end()) {
part->Label.setValue(jt->second);
}
}
// check for colors per face
if (perface && !myColorMap.empty()) {
TopTools_IndexedMapOfShape faces;
TopExp_Explorer xp(shape,TopAbs_FACE);
while (xp.More()) {
faces.Add(xp.Current());
xp.Next();
}
bool found_face_color = false;
std::vector<App::Color> faceColors;
faceColors.resize(faces.Extent(), partColor);
xp.Init(shape,TopAbs_FACE);
while (xp.More()) {
jt = myColorMap.find(xp.Current().HashCode(INT_MAX));
if (jt != myColorMap.end()) {
int index = faces.FindIndex(xp.Current());
App::Color color;
color.r = jt->second.Red();
color.g = jt->second.Green();
color.b = jt->second.Blue();
faceColors[index-1] = color;
found_face_color = true;
}
xp.Next();
}
if (found_face_color) {
Gui::ViewProvider* vp = Gui::Application::Instance->getViewProvider(part);
if (vp && vp->isDerivedFrom(PartGui::ViewProviderPartExt::getClassTypeId())) {
static_cast<PartGui::ViewProviderPartExt*>(vp)->DiffuseColor.setValues(faceColors);
}
}
}
}
void loadShapes(const TDF_Label& label)
{
TopoDS_Shape aShape;
if (aShapeTool->GetShape(label,aShape)) {
//if (aShapeTool->IsReference(label)) {
// TDF_Label reflabel;
// if (aShapeTool->GetReferredShape(label, reflabel)) {
// loadShapes(reflabel);
// }
//}
if (aShapeTool->IsTopLevel(label)) {
int ctSolids = 0, ctShells = 0, ctComps = 0;
// add the shapes
TopExp_Explorer xp;
for (xp.Init(aShape, TopAbs_SOLID); xp.More(); xp.Next(), ctSolids++)
this->mySolids[xp.Current().HashCode(INT_MAX)] = (xp.Current());
for (xp.Init(aShape, TopAbs_SHELL, TopAbs_SOLID); xp.More(); xp.Next(), ctShells++)
this->myShells[xp.Current().HashCode(INT_MAX)] = (xp.Current());
// if no solids and no shells were found then go for compounds
if (ctSolids == 0 && ctShells == 0) {
for (xp.Init(aShape, TopAbs_COMPOUND); xp.More(); xp.Next(), ctComps++)
this->myCompds[xp.Current().HashCode(INT_MAX)] = (xp.Current());
}
if (ctComps == 0) {
for (xp.Init(aShape, TopAbs_FACE, TopAbs_SHELL); xp.More(); xp.Next())
this->myShapes[xp.Current().HashCode(INT_MAX)] = (xp.Current());
for (xp.Init(aShape, TopAbs_WIRE, TopAbs_FACE); xp.More(); xp.Next())
this->myShapes[xp.Current().HashCode(INT_MAX)] = (xp.Current());
for (xp.Init(aShape, TopAbs_EDGE, TopAbs_WIRE); xp.More(); xp.Next())
this->myShapes[xp.Current().HashCode(INT_MAX)] = (xp.Current());
for (xp.Init(aShape, TopAbs_VERTEX, TopAbs_EDGE); xp.More(); xp.Next())
this->myShapes[xp.Current().HashCode(INT_MAX)] = (xp.Current());
}
}
// getting color
Quantity_Color col;
if (hColors->GetColor(label, XCAFDoc_ColorGen, col) ||
hColors->GetColor(label, XCAFDoc_ColorSurf, col) ||
hColors->GetColor(label, XCAFDoc_ColorCurv, col)) {
// add defined color
myColorMap[aShape.HashCode(INT_MAX)] = col;
}
else {
// http://www.opencascade.org/org/forum/thread_17107/
TopoDS_Iterator it;
for (it.Initialize(aShape);it.More(); it.Next()) {
if (hColors->GetColor(it.Value(), XCAFDoc_ColorGen, col) ||
hColors->GetColor(it.Value(), XCAFDoc_ColorSurf, col) ||
hColors->GetColor(it.Value(), XCAFDoc_ColorCurv, col)) {
// add defined color
myColorMap[it.Value().HashCode(INT_MAX)] = col;
}
}
}
// getting names
Handle(TDataStd_Name) name;
if (label.FindAttribute(TDataStd_Name::GetID(),name)) {
TCollection_ExtendedString extstr = name->Get();
char* str = new char[extstr.LengthOfCString()+1];
extstr.ToUTF8CString(str);
std::string label(str);
if (!label.empty())
myNameMap[aShape.HashCode(INT_MAX)] = label;
delete [] str;
}
#if 0
// http://www.opencascade.org/org/forum/thread_15174/
if (aShapeTool->IsAssembly(label)) {
TDF_LabelSequence shapeLabels;
aShapeTool->GetComponents(label, shapeLabels);
Standard_Integer nbShapes = shapeLabels.Length();
for (Standard_Integer i = 1; i <= nbShapes; i++) {
loadShapes(shapeLabels.Value(i));
}
}
#endif
if (label.HasChild()) {
TDF_ChildIterator it;
for (it.Initialize(label); it.More(); it.Next()) {
loadShapes(it.Value());
}
}
}
}
private:
Handle_TDocStd_Document hdoc;
App::Document* doc;
Handle_XCAFDoc_ShapeTool aShapeTool;
Handle_XCAFDoc_ColorTool hColors;
std::string default_name;
std::map<Standard_Integer, TopoDS_Shape> mySolids;
std::map<Standard_Integer, TopoDS_Shape> myShells;
std::map<Standard_Integer, TopoDS_Shape> myCompds;
std::map<Standard_Integer, TopoDS_Shape> myShapes;
std::map<Standard_Integer, Quantity_Color> myColorMap;
std::map<Standard_Integer, std::string> myNameMap;
};
/* module functions */
@ -570,15 +185,9 @@ static PyObject * importer(PyObject *self, PyObject *args)
return 0;
}
#if 1
ImportOCAF ocaf(hDoc, pcDoc, file.fileNamePure());
ImportOCAFExt ocaf(hDoc, pcDoc, file.fileNamePure());
ocaf.loadShapes();
#else
ImportXCAF xcaf(hDoc, pcDoc, file.fileNamePure());
xcaf.loadShapes();
#endif
pcDoc->recompute();
}
catch (Standard_Failure) {
Handle_Standard_Failure e = Standard_Failure::Caught();
@ -606,10 +215,7 @@ static PyObject * exporter(PyObject *self, PyObject *args)
Handle(XCAFApp_Application) hApp = XCAFApp_Application::GetApplication();
Handle(TDocStd_Document) hDoc;
hApp->NewDocument(TCollection_ExtendedString("MDTV-CAF"), hDoc);
Handle_XCAFDoc_ShapeTool hShapeTool = XCAFDoc_DocumentTool::ShapeTool(hDoc->Main());
Handle_XCAFDoc_ColorTool hColors = XCAFDoc_DocumentTool::ColorTool(hDoc->Main());
TDF_Label rootLabel= TDF_TagSource::NewChild(hDoc->Main());
Import::ExportOCAF ocaf(hDoc);
Py::List list(object);
for (Py::List::iterator it = list.begin(); it != list.end(); ++it) {
@ -618,68 +224,14 @@ static PyObject * exporter(PyObject *self, PyObject *args)
App::DocumentObject* obj = static_cast<App::DocumentObjectPy*>(item)->getDocumentObjectPtr();
if (obj->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) {
Part::Feature* part = static_cast<Part::Feature*>(obj);
const TopoDS_Shape& shape = part->Shape.getValue();
// Add shape and name
//TDF_Label shapeLabel = hShapeTool->AddShape(shape, Standard_False);
TDF_Label shapeLabel= TDF_TagSource::NewChild(rootLabel);
#if OCC_VERSION_HEX >= 0x060500
TDataXtd_Shape::Set(shapeLabel, shape);
#else
TDataStd_Shape::Set(shapeLabel, shape);
#endif
TDataStd_Name::Set(shapeLabel, TCollection_ExtendedString(part->Label.getValue(), 1));
// Add color information
Quantity_Color col;
std::vector<App::Color> colors;
Gui::ViewProvider* vp = Gui::Application::Instance->getViewProvider(part);
bool per_face = false;
if (vp && vp->isDerivedFrom(PartGui::ViewProviderPartExt::getClassTypeId())) {
const std::vector<App::Color>& c = static_cast<PartGui::ViewProviderPartExt*>
(vp)->DiffuseColor.getValues();
// define color per face
if (c.size() > 1) {
per_face = true;
std::set<int> face_index;
TopTools_IndexedMapOfShape faces;
TopExp_Explorer xp(shape,TopAbs_FACE);
while (xp.More()) {
face_index.insert(faces.Add(xp.Current()));
xp.Next();
}
xp.Init(shape,TopAbs_FACE);
while (xp.More()) {
int index = faces.FindIndex(xp.Current());
if (face_index.find(index) != face_index.end()) {
face_index.erase(index);
TDF_Label faceLabel= TDF_TagSource::NewChild(shapeLabel);
#if OCC_VERSION_HEX >= 0x060500
TDataXtd_Shape::Set(faceLabel, xp.Current());
#else
TDataStd_Shape::Set(faceLabel, xp.Current());
#endif
const App::Color& color = c[index-1];
Quantity_Parameter mat[3];
mat[0] = color.r;
mat[1] = color.g;
mat[2] = color.b;
col.SetValues(mat[0],mat[1],mat[2],Quantity_TOC_RGB);
hColors->SetColor(faceLabel, col, XCAFDoc_ColorSurf);
}
xp.Next();
}
}
}
if (!per_face && vp && vp->isDerivedFrom(PartGui::ViewProviderPart::getClassTypeId())) {
App::Color color = static_cast<PartGui::ViewProviderPart*>(vp)->ShapeColor.getValue();
Quantity_Parameter mat[3];
mat[0] = color.r;
mat[1] = color.g;
mat[2] = color.b;
col.SetValues(mat[0],mat[1],mat[2],Quantity_TOC_RGB);
hColors->SetColor(shapeLabel, col, XCAFDoc_ColorGen);
colors = static_cast<PartGui::ViewProviderPartExt*>(vp)->DiffuseColor.getValues();
if (colors.empty())
colors.push_back(static_cast<PartGui::ViewProviderPart*>(vp)->ShapeColor.getValue());
}
ocaf.saveShape(part, colors);
}
else {
Base::Console().Message("'%s' is not a shape, export will be ignored.\n", obj->Label.getValue());

View File

@ -22,6 +22,7 @@ link_directories(${OCC_LIBRARY_DIR})
set(ImportGui_LIBS
FreeCADGui
PartGui
Import
${OCC_OCAF_LIBRARIES}
${OCC_OCAF_DEBUG_LIBRARIES}
)

View File

@ -28,11 +28,13 @@
// Importing of App classes
#ifdef FC_OS_WIN32
# define ImportGuiExport __declspec(dllexport)
# define ImportGuiExport __declspec(dllexport)
# define ImportExport __declspec(dllimport)
# define PartExport __declspec(dllimport)
# define PartGuiExport __declspec(dllimport)
#else // for Linux
# define ImportGuiExport
# define ImportExport
# define PartExport
# define PartGuiExport
#endif

View File

@ -70,6 +70,14 @@ public:
/** MeshEdge just a pair of two point indices */
typedef std::pair<unsigned long, unsigned long> MeshEdge;
struct MeshExport EdgeCollapse
{
unsigned long _fromPoint;
unsigned long _toPoint;
std::vector<unsigned long> _removeFacets;
std::vector<unsigned long> _changeFacets;
};
/**
* The MeshPoint class represents a point in the mesh data structure. The class inherits from
* Vector3f and provides some additional information such as flag state and property value.
@ -250,6 +258,10 @@ public:
* Decrement the index for each corner point that is higher than \a ulIndex.
*/
inline void Decrement (unsigned long ulIndex);
/**
* Checks if the facets references the given point index.
*/
inline bool HasPoint(unsigned long) const;
/**
* Replaces the index of the neighbour facet that is equal to \a ulOrig
* by \a ulNew. If the facet does not have a neighbourt with this index
@ -826,6 +838,17 @@ inline void MeshFacet::Decrement (unsigned long ulIndex)
if (_aulPoints[2] > ulIndex) _aulPoints[2]--;
}
inline bool MeshFacet::HasPoint(unsigned long ulIndex) const
{
if (_aulPoints[0] == ulIndex)
return true;
if (_aulPoints[1] == ulIndex)
return true;
if (_aulPoints[2] == ulIndex)
return true;
return false;
}
inline void MeshFacet::ReplaceNeighbour (unsigned long ulOrig, unsigned long ulNew)
{
if (_aulNeighbours[0] == ulOrig)

Some files were not shown because too many files have changed in this diff Show More