Merge branch 'master' of ssh://git.code.sf.net/p/free-cad/code
This commit is contained in:
commit
adaa3716dd
35
README
35
README
|
@ -12,13 +12,20 @@ FreeCAD is based on OpenCasCade, a powerful geometry kernel, features an Open In
|
|||
The interface is built with Qt. FreeCAD runs exactly the same way on Windows, Mac OSX, BSD and
|
||||
Linux platforms.
|
||||
|
||||
Home page and wiki documentation: http://free-cad.sf.net
|
||||
Home page: http://www.freecadweb.org
|
||||
Documentation wiki: http://www.freecadweb.org/wiki
|
||||
Forum: http://sourceforge.net/apps/phpbb/free-cad/
|
||||
Bug tracker: http://sourceforge.net/apps/mantisbt/free-cad/
|
||||
Official git link: git://free-cad.git.sourceforge.net/free-cad/free-cad
|
||||
Git repository: http://sourceforge.net/p/free-cad/code/ci/master/tree/
|
||||
|
||||
Building
|
||||
========
|
||||
Installing
|
||||
==========
|
||||
|
||||
Precompiled (installable) packages are usually available to you from several sources and are
|
||||
described on the FreeCAD download page: http://www.freecadweb.org/wiki/index.php?title=Download
|
||||
|
||||
Compiling
|
||||
=========
|
||||
|
||||
Compiling FreeCAD requires to install several heavyweight libraries and their development
|
||||
files such as OpenCasCADe, Coin and Qt, listed in the pages below. Once this is done,
|
||||
|
@ -31,12 +38,26 @@ Note that autotools build system can still be used but will be obsoleted soon.
|
|||
|
||||
The pages below contain up-to-date build instructions:
|
||||
|
||||
For Linux: http://sourceforge.net/apps/mediawiki/free-cad/index.php?title=CompileOnUnix
|
||||
For windows: http://sourceforge.net/apps/mediawiki/free-cad/index.php?title=CompileOnWindows
|
||||
For Mac OSX: http://sourceforge.net/apps/mediawiki/free-cad/index.php?title=CompileOnMac
|
||||
For Linux: http://www.freecadweb.org/wiki/index.php?title=CompileOnUnix
|
||||
For windows: http://www.freecadweb.org/wiki/index.php?title=CompileOnWindows
|
||||
For Mac OSX: http://www.freecadweb.org/wiki/index.php?title=CompileOnMac
|
||||
|
||||
In this folder you will also find additional README files, specific for each platform.
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
The FreeCAD documentation wiki contains sections for each category of users, and a manual,
|
||||
which is a compilation of the most useful articles of the wiki:
|
||||
|
||||
For users: General FreeCAD usage: http://www.freecadweb.org/wiki/index.php?title=User_hub
|
||||
For power-users: Python scripting: http://www.freecadweb.org/wiki/index.php?title=Power_users_hub
|
||||
For developers: C++ FreeCAD development: http://www.freecadweb.org/wiki/index.php?title=Developer_hub
|
||||
|
||||
The FreeCAD manual: http://www.freecadweb.org/wiki/index.php?title=Online_Help_Toc
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -4,5 +4,6 @@ The FreeCAD Document
|
|||
.. toctree::
|
||||
:maxdepth: 4
|
||||
|
||||
.. automodule:: ActiveDocument
|
||||
:members:
|
||||
.. automodule:: DocumentObject
|
||||
|
||||
|
||||
|
|
18
src/Doc/sphinx/DocumentObject.rst
Normal file
18
src/Doc/sphinx/DocumentObject.rst
Normal file
|
@ -0,0 +1,18 @@
|
|||
The FreeCAD Document Object
|
||||
===========================
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 4
|
||||
|
||||
.. automodule:: DocumentObject
|
||||
|
||||
.. autoclass:: DocumentObject
|
||||
:members:
|
||||
|
||||
.. method:: __setstate__(value)
|
||||
|
||||
allows to save custom attributes of this object as strings, so they can be saved when saving the FreeCAD document
|
||||
|
||||
.. method:: __getstate__()
|
||||
|
||||
reads values previously saved with __setstate__()
|
|
@ -7,14 +7,5 @@ The FreeCAD module
|
|||
.. automodule:: FreeCAD
|
||||
:members:
|
||||
|
||||
.. autoclass:: Vector
|
||||
:members:
|
||||
|
||||
.. autoclass:: Matrix
|
||||
:members:
|
||||
|
||||
.. autoclass:: Placement
|
||||
:members:
|
||||
|
||||
.. autoclass:: Console
|
||||
:members:
|
||||
|
|
10
src/Doc/sphinx/Matrix.rst
Normal file
10
src/Doc/sphinx/Matrix.rst
Normal file
|
@ -0,0 +1,10 @@
|
|||
The Matrix object
|
||||
=================
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 4
|
||||
|
||||
.. automodule:: FreeCAD
|
||||
|
||||
.. autoclass:: Matrix
|
||||
:members:
|
10
src/Doc/sphinx/Placement.rst
Normal file
10
src/Doc/sphinx/Placement.rst
Normal file
|
@ -0,0 +1,10 @@
|
|||
The Placement object
|
||||
====================
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 4
|
||||
|
||||
.. automodule:: FreeCAD
|
||||
|
||||
.. autoclass:: Placement
|
||||
:members:
|
10
src/Doc/sphinx/Vector.rst
Normal file
10
src/Doc/sphinx/Vector.rst
Normal file
|
@ -0,0 +1,10 @@
|
|||
The Vector object
|
||||
=================
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 4
|
||||
|
||||
.. automodule:: FreeCAD
|
||||
|
||||
.. autoclass:: Vector
|
||||
:members:
|
10
src/Doc/sphinx/ViewProvider.rst
Normal file
10
src/Doc/sphinx/ViewProvider.rst
Normal file
|
@ -0,0 +1,10 @@
|
|||
The View Provider object
|
||||
========================
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 4
|
||||
|
||||
.. automodule:: DocumentObject
|
||||
|
||||
.. autoclass:: ViewProvider
|
||||
:members:
|
|
@ -53,9 +53,13 @@ elif commands.getstatusoutput("locate FreeCAD/lib")[0] == 0:
|
|||
path = commands.getstatusoutput("locate FreeCAD/lib")[1].split()[0]
|
||||
sys.path.append(path)
|
||||
|
||||
# locate TemplatePyMod
|
||||
if commands.getstatusoutput("locate TemplatePyMod")[0] == 0:
|
||||
path = commands.getstatusoutput("locate TemplatePyMod")[1].split()[0]
|
||||
sys.path.append(path)
|
||||
|
||||
import FreeCAD, FreeCADGui
|
||||
FreeCADGui.showMainWindow() # this is needed for complete import of GUI modules
|
||||
from FreeCAD import Document
|
||||
|
||||
# -- General configuration -----------------------------------------------------
|
||||
|
||||
|
|
|
@ -13,7 +13,12 @@ This is the complete python API reference of the FreeCAD appication
|
|||
|
||||
FreeCAD.rst
|
||||
FreeCADGui.rst
|
||||
Vector.rst
|
||||
Placement.rst
|
||||
Matrix.rst
|
||||
Document.rst
|
||||
DocumentObject.rst
|
||||
ViewProvider.rst
|
||||
Mesh.rst
|
||||
Part.rst
|
||||
Sketch.rst
|
||||
|
|
|
@ -165,6 +165,9 @@ def removeComponents(objectsList,host=None):
|
|||
s.remove(o)
|
||||
h.Subtractions = s
|
||||
o.ViewObject.show()
|
||||
elif o == s.Base:
|
||||
s.Base = None
|
||||
o.ViewObject.show()
|
||||
elif tp in ["SectionPlane"]:
|
||||
a = h.Objects
|
||||
if o in a:
|
||||
|
@ -569,7 +572,7 @@ class _CommandRemove:
|
|||
def Activated(self):
|
||||
sel = FreeCADGui.Selection.getSelection()
|
||||
FreeCAD.ActiveDocument.openTransaction(str(translate("Arch","Ungrouping")))
|
||||
if Draft.getType(sel[-1]) in ["Wall","Structure"]:
|
||||
if (Draft.getType(sel[-1]) in ["Wall","Structure"]) and (len(sel) > 1):
|
||||
host = sel.pop()
|
||||
ss = "["
|
||||
for o in sel:
|
||||
|
@ -581,7 +584,7 @@ class _CommandRemove:
|
|||
FreeCADGui.doCommand("Arch.removeComponents("+ss+",FreeCAD.ActiveDocument."+host.Name+")")
|
||||
else:
|
||||
FreeCADGui.doCommand("import Arch")
|
||||
FreeCADGui.doCommand("Arch.removeComponents("+ss+")")
|
||||
FreeCADGui.doCommand("Arch.removeComponents(Arch.ActiveDocument."+sel[-1].Name+")")
|
||||
FreeCAD.ActiveDocument.commitTransaction()
|
||||
FreeCAD.ActiveDocument.recompute()
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ __title__="FreeCAD Arch Component"
|
|||
__author__ = "Yorik van Havre"
|
||||
__url__ = "http://free-cad.sourceforge.net"
|
||||
|
||||
import FreeCAD,FreeCADGui
|
||||
import FreeCAD,FreeCADGui,Draft
|
||||
from PyQt4 import QtGui,QtCore
|
||||
from DraftTools import translate
|
||||
|
||||
|
@ -101,7 +101,8 @@ def removeFromComponent(compobject,subobject):
|
|||
l = compobject.Subtractions
|
||||
l.append(subobject)
|
||||
compobject.Subtractions = l
|
||||
subobject.ViewObject.hide()
|
||||
if Draft.getType(subobject) != "Window":
|
||||
subobject.ViewObject.hide()
|
||||
|
||||
|
||||
class ComponentTaskPanel:
|
||||
|
@ -306,7 +307,8 @@ class Component:
|
|||
if prop in ["Additions","Subtractions"]:
|
||||
if hasattr(obj,prop):
|
||||
for o in getattr(obj,prop):
|
||||
o.ViewObject.hide()
|
||||
if Draft.getType(o) != "Window":
|
||||
o.ViewObject.hide()
|
||||
|
||||
def processSubShapes(self,obj,base):
|
||||
"Adds additions and subtractions to a base shape"
|
||||
|
|
|
@ -78,6 +78,8 @@ class _Floor:
|
|||
def __init__(self,obj):
|
||||
obj.addProperty("App::PropertyLength","Height","Base",
|
||||
str(translate("Arch","The height of this floor")))
|
||||
obj.addProperty("App::PropertyPlacement","Placement","Base",
|
||||
str(translate("Arch","The placement of this group")))
|
||||
self.Type = "Floor"
|
||||
obj.Proxy = self
|
||||
self.Object = obj
|
||||
|
@ -90,10 +92,18 @@ class _Floor:
|
|||
self.Type = state
|
||||
|
||||
def execute(self,obj):
|
||||
pass
|
||||
if hasattr(obj,"Placement"):
|
||||
self.OldPlacement = obj.Placement.copy()
|
||||
|
||||
def onChanged(self,obj,prop):
|
||||
self.Object = obj
|
||||
if prop == "Placement":
|
||||
if hasattr(self,"OldPlacement"):
|
||||
delta = obj.Placement.Base.sub(self.OldPlacement.Base)
|
||||
for o in obj.Group:
|
||||
if hasattr(o,"Placement"):
|
||||
o.Placement.move(delta)
|
||||
self.OldPlacement = FreeCAD.Placement(obj.Placement)
|
||||
|
||||
def addObject(self,child):
|
||||
if hasattr(self,"Object"):
|
||||
|
|
|
@ -68,10 +68,19 @@ class _CommandStructure:
|
|||
'ToolTip': QtCore.QT_TRANSLATE_NOOP("Arch_Structure","Creates a structure object from scratch or from a selected object (sketch, wire, face or solid)")}
|
||||
|
||||
def Activated(self):
|
||||
FreeCAD.ActiveDocument.openTransaction(str(translate("Arch","Create Structure")))
|
||||
FreeCADGui.doCommand("import Arch")
|
||||
|
||||
global QtGui, QtCore
|
||||
from PyQt4 import QtGui, QtCore
|
||||
|
||||
self.Length = 0.5
|
||||
self.Width = 0.2
|
||||
self.Height = 1
|
||||
self.continueCmd = False
|
||||
sel = FreeCADGui.Selection.getSelection()
|
||||
if sel:
|
||||
# direct creation
|
||||
FreeCAD.ActiveDocument.openTransaction(str(translate("Arch","Create Structure")))
|
||||
FreeCADGui.doCommand("import Arch")
|
||||
# if selection contains structs and axes, make a system
|
||||
st = Draft.getObjectsOfType(sel,"Structure")
|
||||
ax = Draft.getObjectsOfType(sel,"Axis")
|
||||
|
@ -81,10 +90,90 @@ class _CommandStructure:
|
|||
# else, do normal structs
|
||||
for obj in sel:
|
||||
FreeCADGui.doCommand("Arch.makeStructure(FreeCAD.ActiveDocument." + obj.Name + ")")
|
||||
FreeCAD.ActiveDocument.commitTransaction()
|
||||
FreeCAD.ActiveDocument.recompute()
|
||||
else:
|
||||
FreeCADGui.doCommand("Arch.makeStructure()")
|
||||
# interactive mode
|
||||
import DraftTrackers
|
||||
self.points = []
|
||||
self.tracker = DraftTrackers.boxTracker()
|
||||
self.tracker.on()
|
||||
FreeCADGui.Snapper.getPoint(callback=self.getPoint,movecallback=self.update,extradlg=self.taskbox())
|
||||
|
||||
def getPoint(self,point=None,obj=None):
|
||||
"this function is called by the snapper when it has a 3D point"
|
||||
self.tracker.finalize()
|
||||
if point == None:
|
||||
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)+')')
|
||||
FreeCADGui.doCommand('s.Placement.Base = '+DraftVecUtils.toString(point))
|
||||
FreeCAD.ActiveDocument.commitTransaction()
|
||||
FreeCAD.ActiveDocument.recompute()
|
||||
if self.continueCmd:
|
||||
self.Activated()
|
||||
|
||||
def taskbox(self):
|
||||
"sets up a taskbox widget"
|
||||
w = QtGui.QWidget()
|
||||
w.setWindowTitle(str(translate("Arch","Structure options")))
|
||||
lay0 = QtGui.QVBoxLayout(w)
|
||||
|
||||
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)
|
||||
|
||||
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)
|
||||
|
||||
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)
|
||||
|
||||
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(value4,QtCore.SIGNAL("stateChanged(int)"),self.setContinue)
|
||||
return w
|
||||
|
||||
def update(self,point):
|
||||
"this function is called by the Snapper when the mouse is moved"
|
||||
self.tracker.pos(point)
|
||||
|
||||
def setWidth(self,d):
|
||||
self.Width = d
|
||||
self.tracker.width(d)
|
||||
|
||||
def setHeight(self,d):
|
||||
self.Height = d
|
||||
self.tracker.height(d)
|
||||
|
||||
def setLength(self,d):
|
||||
self.Length = d
|
||||
self.tracker.length(d)
|
||||
|
||||
def setContinue(self,i):
|
||||
self.continueCmd = bool(i)
|
||||
|
||||
class _Structure(ArchComponent.Component):
|
||||
"The Structure object"
|
||||
|
|
|
@ -335,6 +335,19 @@ class _Wall(ArchComponent.Component):
|
|||
self.hideSubobjects(obj,prop)
|
||||
if prop in ["Base","Height","Width","Align","Additions","Subtractions"]:
|
||||
self.createGeometry(obj)
|
||||
# propagate movements to children windows
|
||||
if prop == "Placement":
|
||||
if obj.Shape:
|
||||
if not obj.Shape.isNull():
|
||||
vo = obj.Shape.Placement.Base
|
||||
vn = obj.Placement.Base
|
||||
if not DraftVecUtils.equals(vo,vn):
|
||||
delta = vn.sub(vo)
|
||||
for o in obj.OutList:
|
||||
if (Draft.getType(o) == "Window") or Draft.isClone(o,"Window"):
|
||||
o.Placement.move(delta)
|
||||
|
||||
|
||||
|
||||
def getDefaultValues(self,obj):
|
||||
"returns normal,width,height values from this wall"
|
||||
|
@ -472,6 +485,10 @@ class _ViewProviderWall(ArchComponent.ViewProviderComponent):
|
|||
|
||||
def getIcon(self):
|
||||
import Arch_rc
|
||||
if hasattr(self,"Object"):
|
||||
for o in self.Object.OutList:
|
||||
if Draft.getType(o) == "Wall":
|
||||
return ":/icons/Arch_Wall_Tree_Assembly.svg"
|
||||
return ":/icons/Arch_Wall_Tree.svg"
|
||||
|
||||
def getDisplayModes(self,vobj):
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
# Resource object code
|
||||
#
|
||||
# Created: Sun Mar 24 15:50:46 2013
|
||||
# Created: Wed Apr 17 16:59:58 2013
|
||||
# by: The Resource Compiler for PyQt (Qt v4.8.2)
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
@ -27968,6 +27968,163 @@ qt_resource_data = "\
|
|||
\xba\x70\x69\x20\x5a\xa2\xbd\xe0\xab\x69\x8b\x99\x5e\x5b\x43\xe6\
|
||||
\xc8\x70\xb7\x67\xbb\xbc\x3a\xbb\x70\x5b\x40\x57\x67\xff\x01\xbd\
|
||||
\xf5\xc0\x77\
|
||||
\x00\x00\x09\xaf\
|
||||
\x00\
|
||||
\x00\x5c\xa6\x78\x9c\xed\x5c\x6d\x6f\xdb\x38\x12\xfe\x9e\x5f\xa1\
|
||||
\x73\xbf\xec\xe2\x2c\x9a\xef\x2f\x6e\x92\xc5\xe1\x8a\x05\x16\xb8\
|
||||
\xfb\xb2\xdb\xc3\x7e\x2c\x64\x89\x76\xb4\x95\x25\x43\x92\xe3\xa4\
|
||||
\xbf\xfe\x86\xb2\x2c\x4b\xb6\xeb\xa4\x75\x92\x26\x6b\xb9\x48\x13\
|
||||
\x91\x43\x8a\x1c\x3e\x9c\x79\x66\xc8\xe4\xf2\x97\xbb\x79\xe2\xdd\
|
||||
\xda\xbc\x88\xb3\xf4\x6a\x40\x10\x1e\x78\x36\x0d\xb3\x28\x4e\x67\
|
||||
\x57\x83\xff\x7d\xfc\xd5\xd7\x03\xaf\x28\x83\x34\x0a\x92\x2c\xb5\
|
||||
\x57\x83\x34\x1b\xfc\x72\x7d\x71\xf9\x0f\xdf\xf7\xfe\x9d\xdb\xa0\
|
||||
\xb4\x91\xb7\x8a\xcb\x1b\xef\xb7\xf4\x73\x11\x06\x0b\xeb\xfd\x74\
|
||||
\x53\x96\x8b\xf1\x68\xb4\x5a\xad\x50\x5c\x17\xa2\x2c\x9f\x8d\x7e\
|
||||
\xf6\x7c\xff\xfa\xe2\xe2\xb2\xb8\x9d\x5d\x78\x9e\x07\xef\x4d\x8b\
|
||||
\x71\x14\x5e\x0d\xea\x06\x8b\x65\x9e\x54\x82\x51\x38\xb2\x89\x9d\
|
||||
\xdb\xb4\x2c\x46\x04\x91\xd1\x60\x2b\x1e\x6e\xc5\x43\xf7\xf6\xf8\
|
||||
\xd6\x86\xd9\x7c\x9e\xa5\x45\xd5\x32\x2d\xde\xb5\x84\xf3\x68\xda\
|
||||
\x48\xbb\xd1\xac\x58\x25\x44\x8c\x31\x23\x4c\x47\x94\xfa\x20\xe1\
|
||||
\x17\xf7\x69\x19\xdc\xf9\xdd\xa6\x30\xc6\x43\x4d\x29\xc6\x78\x04\
|
||||
\x75\x5b\xc9\xc7\x49\x8d\x0b\x50\xe8\x02\xbe\x1a\xf1\x4d\x01\x2a\
|
||||
\xb2\x65\x1e\xda\x29\xb4\xb3\x28\xb5\xe5\xe8\xc3\xc7\x0f\x4d\xa5\
|
||||
\x8f\x51\x54\x46\xad\x6e\x36\xfa\xec\xbc\xb5\xa3\xe4\x34\x98\xdb\
|
||||
\x62\x11\x84\xb6\x18\x6d\xca\xab\xf6\xab\x38\x2a\x6f\xae\x06\x92\
|
||||
\x2f\xee\xaa\xe7\x1b\x1b\xcf\x6e\xca\x56\x41\x1c\x5d\x0d\x60\xcc\
|
||||
\x54\x13\x59\x3d\xb7\x20\x41\xd6\x02\x75\x77\xe3\xa6\x06\x23\xae\
|
||||
\x11\x43\xc4\xcb\x8d\xd6\xeb\x56\x9b\x91\x8f\xa3\x2c\x74\x43\xb9\
|
||||
\x1a\xfc\x2b\x0f\x6f\x3e\xfd\x19\x24\xc9\xa7\x8f\xb9\xb5\xc8\xa9\
|
||||
\xe5\x1a\x24\x2f\x23\x3b\x2d\x5c\x8b\xf5\x9b\xdd\x13\xbc\x5a\x57\
|
||||
\x75\x50\xdb\xbc\x6c\x01\x2f\x5b\xd8\xd0\x2d\xf4\x5a\xba\xf5\x8e\
|
||||
\xf2\xde\x69\xa2\x2b\xca\xd6\xea\xf2\x3a\x03\x5e\x7c\xba\x83\xd1\
|
||||
\x7a\x63\x8f\x51\xf8\x8f\x1c\x94\xb8\x5f\x4b\x10\x58\x3b\xf8\x86\
|
||||
\x0f\xca\x7c\x71\xfa\x3a\xd2\x4d\x3d\x02\x3f\xcb\xe3\x59\x0c\x0a\
|
||||
\xaa\xe4\x28\x41\xac\xfa\x74\xdb\xc0\xa4\x5b\x73\xa3\x9a\xf2\x81\
|
||||
\x37\x7a\xc4\xec\x77\x1a\x32\x49\xe9\xc3\x03\xc1\x48\xb8\x49\xd5\
|
||||
\x03\xd9\x1d\x4a\x77\x86\xa4\x92\x14\x27\x29\xaa\x56\xf7\x6e\x37\
|
||||
\x0f\xad\xdc\xf7\x2a\xc0\x37\x67\xae\x02\xc1\xce\x5c\x01\x4a\x9c\
|
||||
\xb9\x02\x8c\x3a\x6f\x05\x28\x7a\x60\x0c\x67\xa5\x00\x7e\xe6\x7e\
|
||||
\x40\x49\x7e\xe6\x0a\xd0\x67\x6e\x04\x35\x96\x67\xaf\x00\xff\xcc\
|
||||
\x99\x80\x66\x7f\xb7\x4d\x70\x39\x72\xc1\x51\xf5\x53\xd3\xc0\x85\
|
||||
\x56\xd1\x6d\x6c\x57\xdb\x08\x6a\x12\x14\xb6\xee\x79\x11\xcc\x20\
|
||||
\x2a\x4e\xb2\xfc\x6a\xf0\x6e\x5a\x7d\xea\x8a\x49\x96\x47\x36\xdf\
|
||||
\x54\xc9\xea\xd3\xa9\xca\x20\x72\x8c\xcb\xfb\x75\x1e\xe0\x62\x47\
|
||||
\x89\xd0\x6b\x53\x8f\x0f\xd7\x17\x37\x41\x94\xad\xae\x06\x74\xb7\
|
||||
\xf2\x4b\x96\xcd\xa1\x57\xb2\x5b\x1e\x82\x6a\x88\x44\x04\x2b\x2e\
|
||||
\xcc\x5e\x25\xbc\x88\x31\x44\x89\x62\x8d\x69\xdb\x56\x2e\xf3\xdc\
|
||||
\xa6\xa5\x9f\x04\xf7\x16\x66\x53\x7d\xdb\x74\x5f\xdc\x64\xab\x59\
|
||||
\xee\xb4\x52\xe6\x4b\xbb\xdb\x12\x42\xd3\xa5\x4b\x2e\xf8\xcb\x34\
|
||||
\x2e\x21\x80\xaf\x03\xe0\x96\x84\x6b\xeb\x4f\x26\xd9\xdd\xe1\x0e\
|
||||
\x8a\x34\x58\x1c\xa9\x76\x35\xfe\x22\x28\x6f\x8a\x23\xf5\x69\x16\
|
||||
\xd9\xaf\xd4\x37\xdd\xfb\x36\x9a\x59\x7f\x1e\x47\x8b\x2c\x4e\xcb\
|
||||
\x07\xa5\x1f\x10\xcc\x26\x7f\xc1\x1e\x39\x36\xb0\x5a\xe2\xc8\xd0\
|
||||
\x56\x71\x0a\xeb\xeb\xd7\xc9\x04\x62\xe8\x1e\x0a\x6a\x89\x4d\x7a\
|
||||
\x81\x60\xa1\xbe\x22\xe2\x36\xc5\x57\xaa\xee\xbf\x5e\x35\x0f\xee\
|
||||
\xe2\x79\xfc\xc5\xc2\xda\xee\x81\xa9\x52\x45\x3d\xfa\x69\x90\x14\
|
||||
\x87\x75\x35\x4b\xb2\x49\x90\x6c\x24\xea\x3d\x36\xb7\x65\x10\x05\
|
||||
\x65\xb0\xdd\x4f\x9b\x12\x88\xcc\xc9\x26\x2b\x91\x47\xd3\xf1\xef\
|
||||
\x1f\x7e\xbd\xae\x37\xf0\x65\x18\x8e\xff\xcc\xf2\xcf\x9b\xfd\xec\
|
||||
\x79\x4e\x20\x98\x64\x4b\x98\xf9\xe0\xba\x29\xbe\x8c\xc2\xf1\x34\
|
||||
\xcb\xe7\x41\x79\x1d\xcf\x61\x97\xb8\xdc\xd0\x3f\xef\xe6\x09\xec\
|
||||
\xec\xa6\xa2\x23\xec\xec\xc1\xb6\xd3\x75\xb7\xb9\x5d\x67\x8a\x0e\
|
||||
\xa6\xcb\xa2\x70\x1e\xbb\x46\xa3\x3f\xca\x38\x49\x7e\x73\x2f\x69\
|
||||
\xcc\x67\xd3\x69\x5c\x26\xf6\xba\x7a\xe7\xfa\xc7\xcd\x2c\x46\xf5\
|
||||
\x34\xea\x49\x8e\x5a\xb3\xbc\x1c\x6d\xd4\x50\x3d\xcd\xb6\xea\xe9\
|
||||
\xec\xb7\x46\xc1\x49\x30\xb1\xa0\xda\xff\xb8\x4a\x6f\xaf\x76\x96\
|
||||
\x67\xcb\xc5\x1c\xd6\xa7\x6e\xde\xa8\x15\x50\xd7\xd8\xc4\xf2\x3e\
|
||||
\x81\xfa\xca\x46\x8d\xdf\xe1\xea\xf3\x7e\x0a\x93\x1a\xbf\x53\x81\
|
||||
\xfb\x57\x3d\xf8\xb5\x21\x1a\x93\xf5\x63\xbe\x4c\xec\xd8\xde\x5a\
|
||||
\x58\xfc\xe8\x7d\x51\xe6\xd9\x67\xdb\x34\x5e\x3f\xae\x31\x3b\x26\
|
||||
\xc8\x68\x0a\x56\x8f\x8a\x4d\x79\x12\xa7\x16\x46\x37\x9e\x2c\xcb\
|
||||
\xb2\x5d\xf6\x17\x6c\xa5\x31\x0c\x38\xdd\x74\x08\xfb\xab\xb4\x79\
|
||||
\x02\xe8\x2b\xc7\x7c\x53\xb6\x1d\x47\x5d\x10\x05\x60\x03\xf3\x3c\
|
||||
\xb8\x1f\xa7\x59\x6a\xdb\xa5\xd9\x74\x5a\xd8\x72\x8c\xdf\xcf\x83\
|
||||
\xfc\xb3\xcd\xd7\xf5\xb7\x71\x11\x4f\xe2\xc4\x75\x51\xfd\x98\xd8\
|
||||
\xf7\x51\x5c\x2c\x40\x3d\xe3\x38\x75\xc3\x78\x9f\xdd\xda\x7c\x9a\
|
||||
\x64\xab\xa6\xde\xa6\x01\x7c\xf3\x27\x41\xf8\x79\x56\x8d\x6f\x1c\
|
||||
\x84\x60\xd0\x96\x49\x50\xda\xad\xf7\x81\x25\x72\x6a\xa5\x9a\x63\
|
||||
\x9f\xf9\xdc\xc7\xbe\xf6\xb7\x9e\xb1\xde\xc0\x1a\x69\x23\x0d\xa3\
|
||||
\x5b\xda\xd4\xa4\x05\x11\x27\x42\x6a\xbc\xa5\xd4\xb0\x5d\x05\x58\
|
||||
\x7d\x8a\x25\xd1\x4d\x21\x6c\x54\x8d\x91\x26\x9a\xc8\x6d\x0a\xa6\
|
||||
\xcc\x83\xb4\x70\xb0\x86\x4d\x14\x94\x79\x7c\xf7\x13\x88\x60\x86\
|
||||
\x15\x36\x72\xe8\x83\x13\x34\x42\x6b\xc6\xc9\x10\x0f\xdd\x17\xfe\
|
||||
\x79\xeb\xe9\x1f\x89\x84\xb5\x53\x3b\x15\x09\x1a\xe6\xc2\x89\x31\
|
||||
\x67\x84\x04\xb5\x8b\x00\xc2\x11\xd1\x9a\x72\x7d\x00\x01\x4c\x02\
|
||||
\x32\x74\x07\x01\x54\x21\x63\x08\x26\xac\x8d\x00\xa6\x11\xc5\x84\
|
||||
\x6a\x79\x14\x01\x46\x50\x26\x25\x83\x15\x47\x0c\x73\x23\x24\xef\
|
||||
\xd7\xff\xc5\xd7\xdf\xf8\xf2\x44\x04\x70\x86\x04\xa1\x42\xec\x00\
|
||||
\x80\x18\x00\x05\x3d\x1d\x00\x8e\x9d\x3c\x02\x00\xa1\x72\xff\x4e\
|
||||
\x05\x80\x52\x52\x09\x82\xf9\xdf\x1b\x00\x8e\xcb\x78\x40\xa3\x35\
|
||||
\xa6\x42\x8a\x21\x27\x88\x33\xa1\x0c\xf3\x48\xb5\x94\x1c\x9b\x21\
|
||||
\x47\xb0\xce\xca\x48\xcf\x57\x88\x70\xae\xa5\x1e\x0a\x58\x24\x22\
|
||||
\x98\xf0\xfc\xad\x98\x5f\xcb\x29\xaf\x11\xf3\x6b\x39\xee\x7d\xf9\
|
||||
\x9a\xef\x11\xd5\xd7\x36\x30\xda\x06\x31\xc0\x04\x1c\x69\x01\xb6\
|
||||
\x16\xba\xcf\x7e\xe8\x14\x66\x29\xac\x48\x99\xe5\x3e\xb0\xfd\xdb\
|
||||
\xa0\x5c\xe6\xd6\x31\xc3\x1e\x2d\xcf\x8c\x16\xae\x91\xd0\x5c\x09\
|
||||
\x40\x8b\x8b\xcd\x84\x24\x7c\x1f\x2d\x6a\x1f\x2d\xfc\x69\xd0\xf2\
|
||||
\x2c\x58\xe9\x49\xe6\x4b\x90\x4c\xb1\xef\x60\xbe\x91\x64\x82\x7d\
|
||||
\x32\xc2\x28\x61\xda\x1e\x46\x3a\x5f\x24\x31\x16\x3d\xc9\x7c\x0b\
|
||||
\x48\xa0\x27\x92\x0c\xa6\x10\xc6\x5c\xd1\x2e\xcd\x84\x45\x65\x4c\
|
||||
\x60\xf6\x62\x34\xb3\xb7\x05\x27\xd8\x82\x53\x83\x4d\xa9\x11\xa7\
|
||||
\x4a\xea\x8e\x1d\x30\x12\x09\xac\xb5\x7c\x49\x3b\xd0\xa3\xe0\x24\
|
||||
\x8f\xb0\x17\x72\x7e\x2b\x0e\x30\x52\x04\xe3\x8e\x29\xd0\x14\x81\
|
||||
\xc9\x68\x1f\xf7\x9c\x00\x83\x9e\x44\x3e\x13\x89\xa4\x88\x69\x69\
|
||||
\x88\x19\x32\x58\x58\xc9\x99\xa6\xc7\x48\xa4\x7a\x1c\x89\x54\x8f\
|
||||
\x23\x91\xf4\xb9\xc3\x8d\x87\x1a\xf5\x88\x7a\x96\x20\xd6\x70\xc1\
|
||||
\xb4\x1a\xba\x70\x16\x48\x95\x22\x9e\x74\xd6\x84\x70\x39\x04\x93\
|
||||
\xc0\x09\x93\xe6\x60\x54\xd2\x48\xf9\xb5\x98\x3e\x06\x1e\xee\x1f\
|
||||
\x38\xa3\xdb\x83\x4f\xcf\x27\x5f\xcc\x8f\xec\xc5\x14\x1c\xc1\xfa\
|
||||
\x6a\xd1\xba\xf1\xd1\xe2\x93\x4a\x77\x2e\x45\xba\xc4\x35\x45\x0a\
|
||||
\x53\x2e\xd4\x0e\x9f\x94\x94\x51\x72\x3c\x71\xdd\xf3\xc9\x57\x81\
|
||||
\x80\x2a\xb6\x3c\x9d\x51\x52\x05\x9b\xbf\xc3\x28\x35\x74\x42\x25\
|
||||
\x7e\x1a\x46\xd9\x3b\x88\x1f\xeb\x20\x84\x42\x0c\x5c\x00\xe1\x2e\
|
||||
\xcb\x09\x7e\x42\x48\xe9\x71\x24\xa1\x88\xb1\x21\x41\xe0\x3b\x04\
|
||||
\x3f\xe8\x1f\x6a\x21\x3e\xf4\xd7\x52\xcc\x1c\xf5\x0f\xdf\xe2\x1d\
|
||||
\x7a\x4c\xfc\x60\xd2\x40\x91\x10\x8a\x4a\x3a\x24\xb0\xb6\xc0\x1f\
|
||||
\x04\xf1\x0c\xa2\x58\x70\xe0\x11\xe0\x17\x60\x51\x09\x90\x06\x42\
|
||||
\x11\x81\x7d\x6d\xd4\x50\x23\x77\x96\x01\x52\x7e\x23\xe6\x37\x72\
|
||||
\x47\xf3\x96\xa4\x75\xf9\xea\xe9\x78\x43\xef\x35\x4e\xf1\x1a\xc0\
|
||||
\xe5\x60\x6d\xc8\xae\xeb\x20\x02\x61\x89\xdb\x8c\x60\xe3\x3a\x34\
|
||||
\xe0\xc0\x18\xae\xba\x27\xdf\xcc\x79\x7f\x21\x3a\x27\xdf\x92\x23\
|
||||
\xc1\x01\x28\x7d\x2e\xe2\x4d\x61\x81\x9f\x88\x05\x2e\x20\x9a\xc5\
|
||||
\x58\x76\xb0\x20\xa0\x0f\xae\x0c\xe5\x3d\x18\xde\x0e\x18\x4e\x04\
|
||||
\x02\x83\xa8\x52\xb2\x4e\x62\x0a\xb0\x01\x51\x26\xe1\x7d\x7e\xf2\
|
||||
\xad\xc0\xc0\xd7\x27\x67\x28\xb9\x41\x46\x61\x4e\x3b\x77\x22\xa4\
|
||||
\x40\x82\x11\xfa\xa2\x99\xea\x3e\xc3\xf0\x9d\x48\x38\xf5\xbc\xca\
|
||||
\x5d\x8b\x72\x11\x45\x07\x01\x94\x22\x03\xc4\x13\xbf\x5c\x7e\xa1\
|
||||
\x5f\xff\xef\xbe\x16\x75\x2a\x02\x38\x43\x5c\x61\xda\x4a\x3b\xd5\
|
||||
\x08\x00\xaa\x20\x9e\xe0\xc4\xb2\x8f\x22\x7f\x78\xea\x59\x49\x4a\
|
||||
\x05\x1f\x52\x89\x88\xd2\x60\xb8\x1f\x75\x23\x66\x7b\x7f\x8a\xec\
|
||||
\x9f\x65\x98\xe6\x2c\x43\x3c\x74\x7d\xea\x9b\x12\xd2\x3d\x58\x7e\
|
||||
\xf0\xc9\x97\x86\xc0\x10\x3e\x6c\xc8\xc0\xc5\xc3\x42\xd3\xa3\xd7\
|
||||
\xa7\xd4\xe3\x2e\xdb\xa9\xc7\xa2\xe5\x39\x0e\x2f\x7a\x92\x79\x52\
|
||||
\xac\x71\x7a\xe6\x9a\x29\x05\xbe\xa1\x93\xb9\x26\x88\x52\xd2\xfa\
|
||||
\xbd\xef\x9e\x60\xbe\x5a\x14\xd0\x93\x6f\xde\xbb\xfc\x24\x66\x86\
|
||||
\xef\x51\x4c\xa0\x0e\x54\xf7\x04\xe3\x0d\x23\xa5\xf2\x19\x44\x23\
|
||||
\xa9\x80\x60\xa8\xa1\xfb\x7b\x31\x42\x18\xa9\x5f\x96\x60\xb4\x8e\
|
||||
\xd7\xfa\x33\xef\xd7\x60\x30\x0e\x9d\x77\x12\xc5\x05\x69\xb9\x81\
|
||||
\xad\xc9\x70\x8b\xac\xb8\x6a\x9b\x0c\xea\xd2\x53\x94\x28\xd9\x31\
|
||||
\x19\xcc\x41\xc3\xe8\x3e\x26\x79\xcb\x58\x59\x9b\x0c\x8c\x20\xb6\
|
||||
\x14\x44\x0f\xc1\x78\x30\x41\x9d\xc9\x50\x48\x62\xc6\x88\x19\x52\
|
||||
\x77\x51\x52\x12\x71\xd0\x62\xac\xa5\x28\x26\xee\x64\xab\x96\x7b\
|
||||
\xd8\x3e\xf4\xb7\x62\x5e\x93\x85\x60\x60\x23\x0e\x65\xb0\x15\x11\
|
||||
\x10\x7c\x1c\xb0\x10\x50\x21\x0d\x21\x1d\x52\x61\x10\x15\x44\x31\
|
||||
\xde\xb6\x10\x10\xb3\x30\x6a\xf8\x53\x58\x88\x1e\x03\xcf\x8f\x81\
|
||||
\xfd\x5f\xe8\x13\xee\xef\x5a\x28\x7a\x00\x02\x40\x2b\x78\x3b\x1d\
|
||||
\xb5\x76\x12\x20\x8d\xb1\xde\x81\x80\xd6\x44\xf3\xe3\xa7\x59\x3d\
|
||||
\x04\x5e\x01\x04\x54\xeb\xce\xc1\x77\x47\x16\x60\x18\x34\xe9\x1a\
|
||||
\x01\x77\x57\x4a\x52\xd9\x23\xe0\xd5\x23\xa0\xa2\x8a\xfb\x09\x6c\
|
||||
\x83\x08\x35\x58\x99\x7d\x14\x08\xa4\x09\xb0\x06\x46\xbb\x76\x40\
|
||||
\x1a\x4c\x88\x22\x3b\x28\xd0\x8c\x4b\xfc\xc4\xbf\xd8\xdb\x93\xc5\
|
||||
\x97\x26\x8b\xff\xf5\x38\x30\x03\xa9\x18\xa6\x43\x82\xa4\x06\x2e\
|
||||
\x60\x84\x27\x38\x32\x8a\x2a\xed\xe2\x4b\xae\x60\xf1\xb5\x74\xb7\
|
||||
\xf6\x35\x61\xda\x80\x1c\x43\xe0\x45\x04\x73\xb9\x6f\x89\x01\x69\
|
||||
\x7c\x08\x8c\x53\x68\x2d\x08\x79\xf0\x1e\x54\x7f\x13\xea\x35\x99\
|
||||
\x88\xed\xed\x97\x27\xb8\x07\x45\xa8\xc2\x9d\x90\xb2\xba\xf4\x80\
|
||||
\xa5\x3e\x6e\x25\xfa\x4b\x0f\xaf\x0c\x0a\xfb\x29\x49\x09\xe6\x40\
|
||||
\xb8\x7b\x8e\x07\xc0\xc0\xb5\xc0\x82\x76\xa2\x07\xe9\xee\xd8\x1a\
|
||||
\xa2\x3a\xf7\xa9\xc1\xa6\x28\x0c\x2e\xe3\xf4\x5b\x71\x97\xa3\xd9\
|
||||
\xf5\xc5\xa5\xfb\x5b\x49\xd7\x17\xff\x07\x1e\x03\x47\xa2\
|
||||
\x00\x00\x08\x6a\
|
||||
\x00\
|
||||
\x00\x47\x9a\x78\x9c\xed\x5a\xdd\x6f\xe3\x36\x12\x7f\xcf\x5f\xa1\
|
||||
|
@ -33045,6 +33202,11 @@ qt_resource_name = "\
|
|||
\x00\x41\
|
||||
\x00\x72\x00\x63\x00\x68\x00\x5f\x00\x43\x00\x65\x00\x6c\x00\x6c\x00\x5f\x00\x54\x00\x72\x00\x65\x00\x65\x00\x2e\x00\x73\x00\x76\
|
||||
\x00\x67\
|
||||
\x00\x1b\
|
||||
\x08\x25\x0d\x47\
|
||||
\x00\x41\
|
||||
\x00\x72\x00\x63\x00\x68\x00\x5f\x00\x57\x00\x61\x00\x6c\x00\x6c\x00\x5f\x00\x54\x00\x72\x00\x65\x00\x65\x00\x5f\x00\x41\x00\x73\
|
||||
\x00\x73\x00\x65\x00\x6d\x00\x62\x00\x6c\x00\x79\x00\x2e\x00\x73\x00\x76\x00\x67\
|
||||
\x00\x0d\
|
||||
\x09\x3c\x92\x47\
|
||||
\x00\x41\
|
||||
|
@ -33179,8 +33341,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\x39\
|
||||
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x1e\x00\x00\x00\x1b\
|
||||
\x00\x00\x00\x10\x00\x02\x00\x00\x00\x01\x00\x00\x00\x3a\
|
||||
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x1f\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\
|
||||
|
@ -33205,35 +33367,36 @@ 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\x06\x5a\x00\x01\x00\x00\x00\x01\x00\x07\xa2\x92\
|
||||
\x00\x00\x05\x3a\x00\x00\x00\x00\x00\x01\x00\x07\x59\x96\
|
||||
\x00\x00\x03\xd6\x00\x00\x00\x00\x00\x01\x00\x06\xfb\x9a\
|
||||
\x00\x00\x07\x8a\x00\x01\x00\x00\x00\x01\x00\x07\xfa\x67\
|
||||
\x00\x00\x06\x2c\x00\x01\x00\x00\x00\x01\x00\x07\x9b\xbd\
|
||||
\x00\x00\x04\x10\x00\x01\x00\x00\x00\x01\x00\x07\x0a\x09\
|
||||
\x00\x00\x04\x62\x00\x01\x00\x00\x00\x01\x00\x07\x1d\x90\
|
||||
\x00\x00\x03\x7a\x00\x01\x00\x00\x00\x01\x00\x06\xe0\xf8\
|
||||
\x00\x00\x07\x24\x00\x00\x00\x00\x00\x01\x00\x07\xd7\x23\
|
||||
\x00\x00\x05\x7a\x00\x00\x00\x00\x00\x01\x00\x07\x73\x70\
|
||||
\x00\x00\x05\x1a\x00\x01\x00\x00\x00\x01\x00\x07\x51\xce\
|
||||
\x00\x00\x03\x58\x00\x01\x00\x00\x00\x01\x00\x06\xd7\xff\
|
||||
\x00\x00\x06\x00\x00\x01\x00\x00\x00\x01\x00\x07\x90\x93\
|
||||
\x00\x00\x06\xfa\x00\x01\x00\x00\x00\x01\x00\x07\xcf\x8e\
|
||||
\x00\x00\x04\x3e\x00\x01\x00\x00\x00\x01\x00\x07\x13\x61\
|
||||
\x00\x00\x03\x0e\x00\x01\x00\x00\x00\x01\x00\x06\xc5\xe9\
|
||||
\x00\x00\x06\x96\x00\x01\x00\x00\x00\x01\x00\x07\xac\x45\
|
||||
\x00\x00\x05\x76\x00\x00\x00\x00\x00\x01\x00\x07\x63\x49\
|
||||
\x00\x00\x04\x12\x00\x00\x00\x00\x00\x01\x00\x07\x05\x4d\
|
||||
\x00\x00\x07\xc6\x00\x01\x00\x00\x00\x01\x00\x08\x04\x1a\
|
||||
\x00\x00\x06\x68\x00\x01\x00\x00\x00\x01\x00\x07\xa5\x70\
|
||||
\x00\x00\x04\x4c\x00\x01\x00\x00\x00\x01\x00\x07\x13\xbc\
|
||||
\x00\x00\x04\x9e\x00\x01\x00\x00\x00\x01\x00\x07\x27\x43\
|
||||
\x00\x00\x03\xb6\x00\x01\x00\x00\x00\x01\x00\x06\xea\xab\
|
||||
\x00\x00\x07\x60\x00\x00\x00\x00\x00\x01\x00\x07\xe0\xd6\
|
||||
\x00\x00\x05\xb6\x00\x00\x00\x00\x00\x01\x00\x07\x7d\x23\
|
||||
\x00\x00\x05\x56\x00\x01\x00\x00\x00\x01\x00\x07\x5b\x81\
|
||||
\x00\x00\x03\x94\x00\x01\x00\x00\x00\x01\x00\x06\xe1\xb2\
|
||||
\x00\x00\x06\x3c\x00\x01\x00\x00\x00\x01\x00\x07\x9a\x46\
|
||||
\x00\x00\x03\x38\x00\x01\x00\x00\x00\x01\x00\x06\xcf\x91\
|
||||
\x00\x00\x05\xaa\x00\x01\x00\x00\x00\x01\x00\x07\x82\xde\
|
||||
\x00\x00\x04\xce\x00\x00\x00\x00\x00\x01\x00\x07\x39\x8b\
|
||||
\x00\x00\x05\xd8\x00\x01\x00\x00\x00\x01\x00\x07\x88\x2e\
|
||||
\x00\x00\x04\xf8\x00\x01\x00\x00\x00\x01\x00\x07\x4a\x0c\
|
||||
\x00\x00\x06\x84\x00\x00\x00\x00\x00\x01\x00\x07\xaa\xd7\
|
||||
\x00\x00\x04\x86\x00\x01\x00\x00\x00\x01\x00\x07\x22\xa7\
|
||||
\x00\x00\x06\xce\x00\x01\x00\x00\x00\x01\x00\x07\xc7\x14\
|
||||
\x00\x00\x06\xae\x00\x01\x00\x00\x00\x01\x00\x07\xbc\xda\
|
||||
\x00\x00\x05\x5a\x00\x01\x00\x00\x00\x01\x00\x07\x6d\x58\
|
||||
\x00\x00\x07\x50\x00\x00\x00\x00\x00\x01\x00\x07\xe8\xf2\
|
||||
\x00\x00\x03\xac\x00\x00\x00\x00\x00\x01\x00\x06\xe9\x3a\
|
||||
\x00\x00\x04\xb0\x00\x00\x00\x00\x00\x01\x00\x07\x2a\x8f\
|
||||
\x00\x00\x07\x36\x00\x01\x00\x00\x00\x01\x00\x07\xd9\x41\
|
||||
\x00\x00\x04\x7a\x00\x01\x00\x00\x00\x01\x00\x07\x1d\x14\
|
||||
\x00\x00\x03\x0e\x00\x01\x00\x00\x00\x01\x00\x06\xc5\xe9\
|
||||
\x00\x00\x03\x74\x00\x01\x00\x00\x00\x01\x00\x06\xd9\x44\
|
||||
\x00\x00\x05\xe6\x00\x01\x00\x00\x00\x01\x00\x07\x8c\x91\
|
||||
\x00\x00\x05\x0a\x00\x00\x00\x00\x00\x01\x00\x07\x43\x3e\
|
||||
\x00\x00\x06\x14\x00\x01\x00\x00\x00\x01\x00\x07\x91\xe1\
|
||||
\x00\x00\x05\x34\x00\x01\x00\x00\x00\x01\x00\x07\x53\xbf\
|
||||
\x00\x00\x06\xc0\x00\x00\x00\x00\x00\x01\x00\x07\xb4\x8a\
|
||||
\x00\x00\x04\xc2\x00\x01\x00\x00\x00\x01\x00\x07\x2c\x5a\
|
||||
\x00\x00\x07\x0a\x00\x01\x00\x00\x00\x01\x00\x07\xd0\xc7\
|
||||
\x00\x00\x06\xea\x00\x01\x00\x00\x00\x01\x00\x07\xc6\x8d\
|
||||
\x00\x00\x05\x96\x00\x01\x00\x00\x00\x01\x00\x07\x77\x0b\
|
||||
\x00\x00\x07\x8c\x00\x00\x00\x00\x00\x01\x00\x07\xf2\xa5\
|
||||
\x00\x00\x03\xe8\x00\x00\x00\x00\x00\x01\x00\x06\xf2\xed\
|
||||
\x00\x00\x04\xec\x00\x00\x00\x00\x00\x01\x00\x07\x34\x42\
|
||||
\x00\x00\x02\xda\x00\x01\x00\x00\x00\x01\x00\x06\xbe\x99\
|
||||
\x00\x00\x02\xb2\x00\x01\x00\x00\x00\x01\x00\x06\xb6\xfd\
|
||||
"
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
<file>icons/Arch_Check.svg</file>
|
||||
<file>icons/Arch_SelectNonManifold.svg</file>
|
||||
<file>icons/Arch_MergeWalls.svg</file>
|
||||
<file>icons/Arch_Wall_Tree_Assembly.svg</file>
|
||||
<file>ui/archprefs-base.ui</file>
|
||||
<file>translations/Arch_af.qm</file>
|
||||
<file>translations/Arch_de.qm</file>
|
||||
|
|
415
src/Mod/Arch/Resources/icons/Arch_Wall_Tree_Assembly.svg
Normal file
415
src/Mod/Arch/Resources/icons/Arch_Wall_Tree_Assembly.svg
Normal file
|
@ -0,0 +1,415 @@
|
|||
<?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:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="64px"
|
||||
height="64px"
|
||||
id="svg2816"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.3.1 r9886"
|
||||
sodipodi:docname="Arch_Wall_Tree.svg">
|
||||
<defs
|
||||
id="defs2818">
|
||||
<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="perspective2824" />
|
||||
<inkscape:perspective
|
||||
id="perspective3622"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<inkscape:perspective
|
||||
id="perspective3622-9"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<inkscape:perspective
|
||||
id="perspective3653"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<inkscape:perspective
|
||||
id="perspective3675"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<inkscape:perspective
|
||||
id="perspective3697"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<inkscape:perspective
|
||||
id="perspective3720"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<inkscape:perspective
|
||||
id="perspective3742"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<inkscape:perspective
|
||||
id="perspective3764"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<inkscape:perspective
|
||||
id="perspective3785"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<inkscape:perspective
|
||||
id="perspective3806"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<inkscape:perspective
|
||||
id="perspective3806-3"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<inkscape:perspective
|
||||
id="perspective3835"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="11"
|
||||
inkscape:cx="16.107459"
|
||||
inkscape:cy="33.217385"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
inkscape:document-units="px"
|
||||
inkscape:grid-bbox="true"
|
||||
inkscape:snap-bbox="true"
|
||||
inkscape:bbox-paths="true"
|
||||
inkscape:bbox-nodes="true"
|
||||
inkscape:snap-bbox-edge-midpoints="true"
|
||||
inkscape:snap-bbox-midpoints="true"
|
||||
inkscape:object-paths="true"
|
||||
inkscape:object-nodes="true"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1057"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:snap-nodes="false"
|
||||
inkscape:snap-global="false" />
|
||||
<metadata
|
||||
id="metadata2821">
|
||||
<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">
|
||||
<rect
|
||||
style="color:#000000;fill:#7a7a7a;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.98266625;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect2840-3-4-0-8-5"
|
||||
width="8.8969326"
|
||||
height="6.4156804"
|
||||
x="50.020618"
|
||||
y="80.818169"
|
||||
transform="matrix(0.80307096,-0.59588341,0,1,0,0)" />
|
||||
<rect
|
||||
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.82064199;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect2840-7"
|
||||
width="14.188248"
|
||||
height="6.3632684"
|
||||
x="27.991013"
|
||||
y="38.201286"
|
||||
transform="matrix(0.95236631,0.3049564,0,1,0,0)" />
|
||||
<rect
|
||||
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.82064199;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect2840-9-6"
|
||||
width="14.188248"
|
||||
height="6.3632684"
|
||||
x="43.51255"
|
||||
y="38.190132"
|
||||
transform="matrix(0.95236631,0.3049564,0,1,0,0)" />
|
||||
<path
|
||||
style="color:#000000;fill:#c7c7c7;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.77675104;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="m 33.802565,41.435793 13.512409,4.326796 -7.144868,5.301535 -13.512409,-4.326797 7.144868,-5.301534 z"
|
||||
id="rect2840-3-5-3-5-0"
|
||||
sodipodi:nodetypes="ccccc"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="color:#000000;fill:#c7c7c7;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.77675104;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="m 48.584755,46.105614 13.512409,4.326797 -7.144868,5.301534 -13.512409,-4.326797 7.144868,-5.301534 z"
|
||||
id="rect2840-3-5-3-0"
|
||||
sodipodi:nodetypes="ccccc"
|
||||
inkscape:connector-curvature="0" />
|
||||
<rect
|
||||
style="color:#000000;fill:#7a7a7a;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.98266625;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect2840-3-4-0-5-6"
|
||||
width="8.8969326"
|
||||
height="6.4156804"
|
||||
x="41.959759"
|
||||
y="66.366005"
|
||||
transform="matrix(0.80307096,-0.59588341,0,1,0,0)" />
|
||||
<rect
|
||||
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.82064199;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect2840-3-2"
|
||||
width="14.188248"
|
||||
height="6.3632684"
|
||||
x="37.004723"
|
||||
y="30.533503"
|
||||
transform="matrix(0.95236631,0.3049564,0,1,0,0)" />
|
||||
<rect
|
||||
style="color:#000000;fill:#7a7a7a;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.98266625;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect2840-3-4-5"
|
||||
width="8.8969326"
|
||||
height="6.4156804"
|
||||
x="68.427689"
|
||||
y="96.508865"
|
||||
transform="matrix(0.80307096,-0.59588341,0,1,0,0)" />
|
||||
<rect
|
||||
style="color:#000000;fill:#7a7a7a;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.98266625;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect2840-3-4-0-7"
|
||||
width="8.8969326"
|
||||
height="6.4156804"
|
||||
x="60.71003"
|
||||
y="82.268806"
|
||||
transform="matrix(0.80307096,-0.59588341,0,1,0,0)" />
|
||||
<path
|
||||
style="color:#000000;fill:#c7c7c7;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.77675104;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="m 42.386919,36.464382 13.512409,4.326797 -7.144867,5.301534 -13.512409,-4.326797 7.144867,-5.301534 z"
|
||||
id="rect2840-3-5-2"
|
||||
sodipodi:nodetypes="ccccc"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#000000;fill:#c7c7c7;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.77675104;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="m 33.945387,33.819971 6.896146,2.241369 -7.144868,5.301534 -6.896146,-2.241368 z"
|
||||
id="rect2840-3-5-4-1"
|
||||
sodipodi:nodetypes="ccccc" />
|
||||
<rect
|
||||
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.82064199;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect2840-3-6"
|
||||
width="4.8688564"
|
||||
height="6.3783622"
|
||||
x="52.702457"
|
||||
y="30.623219"
|
||||
transform="matrix(0.95236631,0.3049564,0,1,0,0)" />
|
||||
<rect
|
||||
style="color:#000000;fill:#7a7a7a;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.98266625;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect2840-3-4-0-5"
|
||||
width="8.8969326"
|
||||
height="6.4156804"
|
||||
x="68.274139"
|
||||
y="88.826065"
|
||||
transform="matrix(0.80307096,-0.59588341,0,1,0,0)" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#000000;fill:#c7c7c7;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.77675104;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="m 57.336914,41.387566 4.636933,1.45354 -7.144868,5.301534 -4.636934,-1.453539 z"
|
||||
id="rect2840-3-5-4"
|
||||
sodipodi:nodetypes="ccccc" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#000000;fill:#c7c7c7;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.77675104;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="m 32.557262,11.494551 9.205487,2.784019 -12.158897,8.901351 -9.205487,-2.784019 z"
|
||||
id="rect2840-3-5-3-1-3"
|
||||
sodipodi:nodetypes="ccccc" />
|
||||
<rect
|
||||
style="color:#000000;fill:#7a7a7a;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.98266625;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect2840-3-4-04-1-5-1"
|
||||
width="15.060457"
|
||||
height="8.1599474"
|
||||
x="53.304558"
|
||||
y="64.54351"
|
||||
transform="matrix(0.80307096,-0.59588341,0,1,0,0)" />
|
||||
<rect
|
||||
style="color:#000000;fill:#7a7a7a;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.98266625;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect2840-3-4-04-1-5-4"
|
||||
width="15.060457"
|
||||
height="8.1599474"
|
||||
x="45.460068"
|
||||
y="55.047924"
|
||||
transform="matrix(0.80307096,-0.59588341,0,1,0,0)" />
|
||||
<rect
|
||||
style="color:#000000;fill:#7a7a7a;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.98266625;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect2840-3-4-04-1"
|
||||
width="15.060457"
|
||||
height="8.1599474"
|
||||
x="36.8633"
|
||||
y="45.146145"
|
||||
transform="matrix(0.80307096,-0.59588341,0,1,0,0)" />
|
||||
<rect
|
||||
style="color:#000000;fill:#7a7a7a;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.98266625;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect2840-3-4-0-8-7"
|
||||
width="8.8969326"
|
||||
height="6.4156804"
|
||||
x="49.970425"
|
||||
y="65.531265"
|
||||
transform="matrix(0.80307096,-0.59588341,0,1,0,0)" />
|
||||
<rect
|
||||
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.82064199;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect2840-2"
|
||||
width="14.188248"
|
||||
height="6.3632684"
|
||||
x="27.948685"
|
||||
y="22.957209"
|
||||
transform="matrix(0.95236631,0.3049564,0,1,0,0)" />
|
||||
<rect
|
||||
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.82064199;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect2840-9-2"
|
||||
width="14.188248"
|
||||
height="6.3632684"
|
||||
x="43.470222"
|
||||
y="22.946053"
|
||||
transform="matrix(0.95236631,0.3049564,0,1,0,0)" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#000000;fill:#c7c7c7;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.77675104;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="m 33.762254,26.178803 13.512409,4.326797 -7.144868,5.301535 -13.51241,-4.326797 7.144869,-5.301535 z"
|
||||
id="rect2840-3-5-3-5-1"
|
||||
sodipodi:nodetypes="ccccc" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#000000;fill:#c7c7c7;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.77675104;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="m 48.544443,30.848624 13.512409,4.326797 -7.144867,5.301535 -13.512409,-4.326797 7.144867,-5.301535 z"
|
||||
id="rect2840-3-5-3-1"
|
||||
sodipodi:nodetypes="ccccc" />
|
||||
<rect
|
||||
style="color:#000000;fill:#7a7a7a;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.98266625;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect2840-3-4-04"
|
||||
width="8.8969326"
|
||||
height="6.4156804"
|
||||
x="68.377495"
|
||||
y="81.22197"
|
||||
transform="matrix(0.80307096,-0.59588341,0,1,0,0)" />
|
||||
<rect
|
||||
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.82064199;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect2840-2-7"
|
||||
width="14.188248"
|
||||
height="6.3632684"
|
||||
x="12.103945"
|
||||
y="22.966328"
|
||||
transform="matrix(0.95236631,0.3049564,0,1,0,0)" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#000000;fill:#c7c7c7;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.77675104;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="m 18.672257,21.355968 13.512409,4.326797 -7.144868,5.301535 -13.51241,-4.326797 7.144869,-5.301535 z"
|
||||
id="rect2840-3-5-3-5-1-5"
|
||||
sodipodi:nodetypes="ccccc" />
|
||||
<rect
|
||||
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.82064199;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect2840-2-7-5"
|
||||
width="8.1745195"
|
||||
height="6.0153747"
|
||||
x="2.8632176"
|
||||
y="23.144983"
|
||||
transform="matrix(0.95236631,0.3049564,0,1,0,0)" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#000000;fill:#c7c7c7;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.77675104;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="m 10.053518,18.352968 7.603319,2.508615 -7.144868,5.301535 -7.6033201,-2.508615 z"
|
||||
id="rect2840-3-5-3-5-1-5-1"
|
||||
sodipodi:nodetypes="ccccc" />
|
||||
<rect
|
||||
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.82064199;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect2840-3-2-1"
|
||||
width="15.715544"
|
||||
height="6.7156911"
|
||||
x="19.251734"
|
||||
y="30.329483"
|
||||
transform="matrix(0.95236631,0.3049564,0,1,0,0)" />
|
||||
<rect
|
||||
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.82064199;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect2840-3-2-6"
|
||||
width="15.33372"
|
||||
height="6.5594053"
|
||||
x="2.8333008"
|
||||
y="30.881844"
|
||||
transform="matrix(0.95236631,0.3049564,0,1,0,0)" />
|
||||
<rect
|
||||
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.82064199;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect2840-7-3"
|
||||
width="14.188248"
|
||||
height="6.3632684"
|
||||
x="12.569814"
|
||||
y="38.276264"
|
||||
transform="matrix(0.95236631,0.3049564,0,1,0,0)" />
|
||||
<rect
|
||||
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.82064199;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect2840-2-7-5-2"
|
||||
width="9.1290798"
|
||||
height="5.8151832"
|
||||
x="2.6901171"
|
||||
y="38.834602"
|
||||
transform="matrix(0.95236631,0.3049564,0,1,0,0)" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#000000;fill:#c7c7c7;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.77675104;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="M 45.767302,1.6871595 54.972789,4.4711786 42.813892,13.37253 33.608404,10.588511 z"
|
||||
id="rect2840-3-5-3-1-3-3"
|
||||
sodipodi:nodetypes="ccccc" />
|
||||
<rect
|
||||
style="color:#000000;fill:#7a7a7a;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.98266625;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect2840-3-4-04-1-5"
|
||||
width="15.060457"
|
||||
height="8.1599474"
|
||||
x="53.312706"
|
||||
y="45.140682"
|
||||
transform="matrix(0.80307096,-0.59588341,0,1,0,0)" />
|
||||
<rect
|
||||
style="color:#000000;fill:#7a7a7a;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.98266625;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect2840-3-4-04-1-5-7"
|
||||
width="6.9758401"
|
||||
height="8.4850521"
|
||||
x="61.389179"
|
||||
y="54.704601"
|
||||
transform="matrix(0.80307096,-0.59588341,0,1,0,0)" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 23 KiB |
|
@ -21,10 +21,18 @@
|
|||
#* *
|
||||
#***************************************************************************
|
||||
|
||||
import FreeCAD,FreeCADGui,Arch,Draft
|
||||
"FreeCAD webgl exporter"
|
||||
|
||||
import FreeCAD,Draft,Part,DraftGeomUtils
|
||||
from DraftTools import translate
|
||||
|
||||
if FreeCAD.GuiUp:
|
||||
import FreeCADGui
|
||||
else:
|
||||
FreeCADGui = None
|
||||
|
||||
tab = " "
|
||||
addWireframe = False
|
||||
|
||||
if open.__module__ == '__builtin__':
|
||||
pythonopen = open
|
||||
|
@ -32,59 +40,51 @@ if open.__module__ == '__builtin__':
|
|||
def export(exportList,filename):
|
||||
"exports the given objects to a .html file"
|
||||
|
||||
# get three.min.js
|
||||
threejspath = Arch.download("https://raw.github.com/mrdoob/three.js/master/build/three.min.js")
|
||||
threejsfile = pythonopen(threejspath,"r")
|
||||
threeminjs = threejsfile.read()
|
||||
threejsfile.close()
|
||||
html = getHTML(exportList)
|
||||
outfile = pythonopen(filename,"wb")
|
||||
outfile.write(html)
|
||||
outfile.close()
|
||||
FreeCAD.Console.PrintMessage(str(translate("Arch","successfully written "))+filename)
|
||||
|
||||
def getHTML(objectsList):
|
||||
"returns the complete HTML code of a viewer for the given objects"
|
||||
|
||||
# get objects data
|
||||
objectsData = ''
|
||||
for obj in exportList:
|
||||
for obj in objectsList:
|
||||
objectsData += getObjectData(obj)
|
||||
|
||||
# build the final file
|
||||
template = getTemplate()
|
||||
template = template.replace("$ThreeMinJs",threeminjs)
|
||||
template = template.replace("$CameraData",getCameraData())
|
||||
template = template.replace("$ObjectsData",objectsData)
|
||||
template = template.replace("$TestData",getTestData())
|
||||
outfile = pythonopen(filename,"wb")
|
||||
outfile.write(template)
|
||||
outfile.close()
|
||||
FreeCAD.Console.PrintMessage(str(translate("Arch","successfully written "))+filename)
|
||||
return template
|
||||
|
||||
def getCameraData():
|
||||
"returns the position and direction of the camera as three.js snippet"
|
||||
|
||||
# getting camera position
|
||||
pos = FreeCADGui.ActiveDocument.ActiveView.viewPosition().Base
|
||||
#result = "camera.position.set( -10,5,15" # test position
|
||||
result = "camera.position.set( "
|
||||
result += str(pos.x) + ", "
|
||||
result += str(pos.y) + ", "
|
||||
result += str(pos.z)
|
||||
|
||||
# getting camera lookat vector
|
||||
lookat = FreeCADGui.ActiveDocument.ActiveView.getViewDirection()
|
||||
lookat = pos.add(lookat)
|
||||
result += " );\n"+tab+"camera.lookAt( scene.position );\n"+tab
|
||||
#result += " );\n"+tab+"camera.lookAt( "
|
||||
#result += str(lookat.x) + ", "
|
||||
#result += str(lookat.y) + ", "
|
||||
#result += str(lookat.z)
|
||||
#result += " );\n"+tab
|
||||
|
||||
result = ""
|
||||
if FreeCADGui:
|
||||
# getting camera position
|
||||
pos = FreeCADGui.ActiveDocument.ActiveView.viewPosition().Base
|
||||
result += "camera.position.set( "
|
||||
result += str(pos.x) + ", "
|
||||
result += str(pos.y) + ", "
|
||||
result += str(pos.z) + " );\n"
|
||||
else:
|
||||
result += "camera.position.set(0,0,1000);\n"
|
||||
result += tab+"camera.lookAt( scene.position );\n"+tab
|
||||
# print result
|
||||
return result
|
||||
|
||||
def getObjectData(obj):
|
||||
"returns the geometry data of an object as three.js snippet"
|
||||
def getObjectData(obj,wireframeMode="faceloop"):
|
||||
"""returns the geometry data of an object as three.js snippet. wireframeMode
|
||||
can be multimaterial, faceloop or None"""
|
||||
|
||||
result = ""
|
||||
wires = []
|
||||
|
||||
if obj.isDerivedFrom("Part::Feature"):
|
||||
fcmesh = obj.Shape.tessellate(0.1)
|
||||
result = "var geom = new THREE.Geometry();\n"
|
||||
|
||||
# adding vertices data
|
||||
for i in range(len(fcmesh[0])):
|
||||
v = fcmesh[0][i]
|
||||
|
@ -92,33 +92,70 @@ def getObjectData(obj):
|
|||
result += tab+"console.log(geom.vertices)\n"
|
||||
for i in range(len(fcmesh[0])):
|
||||
result += tab+"geom.vertices.push(v"+str(i)+");\n"
|
||||
|
||||
# adding facets data
|
||||
for f in fcmesh[1]:
|
||||
result += tab+"geom.faces.push( new THREE.Face3"+str(f)+" );\n"
|
||||
for f in obj.Shape.Faces:
|
||||
for w in f.Wires:
|
||||
wo = Part.Wire(DraftGeomUtils.sortEdges(w.Edges))
|
||||
p = []
|
||||
for v in wo.Vertexes:
|
||||
p.append(v.Point)
|
||||
p.append(wo.Vertexes[0].Point)
|
||||
wires.append(p)
|
||||
|
||||
# adding material
|
||||
col = obj.ViewObject.ShapeColor
|
||||
rgb = Draft.getrgb(col,testbw=False)
|
||||
#rgb = "#888888" # test color
|
||||
result += tab+"var material = new THREE.MeshBasicMaterial( { color: 0x"+str(rgb)[1:]+" } );\n"
|
||||
elif obj.isDerivedFrom("Mesh::Feature"):
|
||||
mesh = obj.Mesh
|
||||
result = "var geom = new THREE.Geometry();\n"
|
||||
# adding vertices data
|
||||
for p in mesh.Points:
|
||||
v = p.Vector
|
||||
i = p.Index
|
||||
result += tab+"var v"+str(i)+" = new THREE.Vector3("+str(v.x)+","+str(v.y)+","+str(v.z)+");\n"
|
||||
result += tab+"console.log(geom.vertices)\n"
|
||||
for p in mesh.Points:
|
||||
result += tab+"geom.vertices.push(v"+str(p.Index)+");\n"
|
||||
# adding facets data
|
||||
for f in mesh.Facets:
|
||||
result += tab+"geom.faces.push( new THREE.Face3"+str(f.PointIndices)+" );\n"
|
||||
|
||||
# adding the mesh to the scene
|
||||
result += tab+"var mesh = new THREE.Mesh( geom, material );\n"
|
||||
result += tab+"scene.add( mesh );\n"+tab
|
||||
if result:
|
||||
# adding a base material
|
||||
if FreeCADGui:
|
||||
col = obj.ViewObject.ShapeColor
|
||||
rgb = Draft.getrgb(col,testbw=False)
|
||||
else:
|
||||
rgb = "#888888" # test color
|
||||
result += tab+"var basematerial = new THREE.MeshBasicMaterial( { color: 0x"+str(rgb)[1:]+" } );\n"
|
||||
#result += tab+"var basematerial = new THREE.MeshLambertMaterial( { color: 0x"+str(rgb)[1:]+" } );\n"
|
||||
|
||||
# print result
|
||||
return result
|
||||
if wireframeMode == "faceloop":
|
||||
# adding the mesh to the scene with a wireframe copy
|
||||
result += tab+"var mesh = new THREE.Mesh( geom, basematerial );\n"
|
||||
result += tab+"scene.add( mesh );\n"
|
||||
result += tab+"var linematerial = new THREE.LineBasicMaterial({color: 0x000000,});\n"
|
||||
for w in wires:
|
||||
result += tab+"var wire = new THREE.Geometry();\n"
|
||||
for p in w:
|
||||
result += tab+"wire.vertices.push(new THREE.Vector3("
|
||||
result += str(p.x)+", "+str(p.y)+", "+str(p.z)+"));\n"
|
||||
result += tab+"var line = new THREE.Line(wire, linematerial);\n"
|
||||
result += tab+"scene.add(line);\n"
|
||||
|
||||
def getTestData():
|
||||
"returns a simple cube as three.js snippet"
|
||||
elif wireframeMode == "multimaterial":
|
||||
# adding a wireframe material
|
||||
result += tab+"var wireframe = new THREE.MeshBasicMaterial( { color: "
|
||||
result += "0x000000, wireframe: true, transparent: true } );\n"
|
||||
result += tab+"var material = [ basematerial, wireframe ];\n"
|
||||
result += tab+"var mesh = new THREE.SceneUtils.createMultiMaterialObject( geom, material );\n"
|
||||
result += tab+"scene.add( mesh );\n"+tab
|
||||
|
||||
#return """var geometry = new THREE.CubeGeometry( .5, .5, .5 );
|
||||
# var material = new THREE.MeshLambertMaterial( { color: 0xFF0000 } );
|
||||
# var mesh = new THREE.Mesh( geometry, material );
|
||||
# scene.add( mesh );"""
|
||||
else:
|
||||
# adding the mesh to the scene with simple material
|
||||
result += tab+"var mesh = new THREE.Mesh( geom, basematerial );\n"
|
||||
result += tab+"scene.add( mesh );\n"+tab
|
||||
|
||||
return ""
|
||||
return result
|
||||
|
||||
def getTemplate():
|
||||
"returns a html template"
|
||||
|
@ -127,35 +164,60 @@ def getTemplate():
|
|||
<html>
|
||||
<head>
|
||||
<title>FreeCAD model</title>
|
||||
<script>$ThreeMinJs</script>
|
||||
<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/three.js/r50/three.min.js"></script>
|
||||
|
||||
<script>
|
||||
|
||||
var camera, controls, scene, renderer;
|
||||
|
||||
window.onload = function() {
|
||||
|
||||
var renderer = new THREE.WebGLRenderer();
|
||||
renderer.setSize( 800, 600 );
|
||||
var SCREEN_WIDTH = window.innerWidth, SCREEN_HEIGHT = window.innerHeight;
|
||||
var VIEW_ANGLE = 35, ASPECT = SCREEN_WIDTH / SCREEN_HEIGHT, NEAR = 0.1, FAR = 20000;
|
||||
|
||||
renderer = new THREE.WebGLRenderer();
|
||||
renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
|
||||
document.body.appendChild( renderer.domElement );
|
||||
|
||||
var scene = new THREE.Scene();
|
||||
scene = new THREE.Scene();
|
||||
|
||||
var camera = new THREE.PerspectiveCamera(
|
||||
35, // Field of view
|
||||
800 / 600, // Aspect ratio
|
||||
0.1, // Near plane
|
||||
10000 // Far plane
|
||||
camera = new THREE.PerspectiveCamera(
|
||||
VIEW_ANGLE, // Field of view
|
||||
ASPECT, // Aspect ratio
|
||||
NEAR, // Near plane
|
||||
FAR // Far plane
|
||||
);
|
||||
$CameraData // placeholder for the FreeCAD camera
|
||||
|
||||
$TestData // placeholder for a test cube
|
||||
controls = new THREE.TrackballControls( camera );
|
||||
controls.rotateSpeed = 1.0;
|
||||
controls.zoomSpeed = 1.2;
|
||||
controls.panSpeed = 0.8;
|
||||
controls.noZoom = false;
|
||||
controls.noPan = false;
|
||||
controls.staticMoving = true;
|
||||
controls.dynamicDampingFactor = 0.3;
|
||||
controls.keys = [ 65, 83, 68 ];
|
||||
|
||||
$ObjectsData // placeholder for the FreeCAD objects
|
||||
|
||||
var light = new THREE.PointLight( 0xFFFF00 );
|
||||
light.position.set( -10, -10, 10 );
|
||||
light.position.set( -10000, -10000, 10000 );
|
||||
scene.add( light );
|
||||
|
||||
renderer.render( scene, camera );
|
||||
|
||||
animate();
|
||||
};
|
||||
|
||||
function animate(){
|
||||
requestAnimationFrame( animate );
|
||||
render();
|
||||
};
|
||||
|
||||
function render(){
|
||||
controls.update();
|
||||
renderer.render( scene, camera );
|
||||
};
|
||||
</script>
|
||||
</head>
|
||||
|
|
|
@ -13,6 +13,7 @@ SET(Draft_SRCS
|
|||
importDXF.py
|
||||
importOCA.py
|
||||
importSVG.py
|
||||
importDWG.py
|
||||
importAirfoilDAT.py
|
||||
macros.py
|
||||
Draft_rc.py
|
||||
|
|
|
@ -101,7 +101,7 @@ def getParamType(param):
|
|||
"modalt"]:
|
||||
return "int"
|
||||
elif param in ["constructiongroupname","textfont","patternFile","template","maxSnapEdges",
|
||||
"snapModes"]:
|
||||
"snapModes","FontFile"]:
|
||||
return "string"
|
||||
elif param in ["textheight","tolerance","gridSpacing"]:
|
||||
return "float"
|
||||
|
@ -143,6 +143,11 @@ def tolerance():
|
|||
"tolerance(): returns the tolerance value from Draft user settings"
|
||||
return getParam("tolerance")
|
||||
|
||||
def epsilon():
|
||||
''' epsilon(): returns a small number based on Draft.tolerance() for use in
|
||||
floating point comparisons. Use with caution. '''
|
||||
return (1.0/(10.0**tolerance()))
|
||||
|
||||
def getRealName(name):
|
||||
"getRealName(string): strips the trailing numbers from a string name"
|
||||
for i in range(1,len(name)):
|
||||
|
@ -803,17 +808,24 @@ def makeArray(baseobject,arg1,arg2,arg3,arg4=None):
|
|||
select(obj)
|
||||
return obj
|
||||
|
||||
def makeEllipse(majradius,minradius,placement=None):
|
||||
'''makeEllipse(majradius,minradius,[placement]): makes
|
||||
def makeEllipse(majradius,minradius,placement=None,face=True,support=None):
|
||||
'''makeEllipse(majradius,minradius,[placement],[face],[support]): makes
|
||||
an ellipse with the given major and minor radius, and optionally
|
||||
a placement.'''
|
||||
import Part
|
||||
e = Part.Ellipse(FreeCAD.Vector(0,0,0),majradius,minradius)
|
||||
newobj = FreeCAD.ActiveDocument.addObject("Part::Feature","Ellipse")
|
||||
newobj.Shape = e.toShape()
|
||||
if placement: newobj.Placement = placement
|
||||
FreeCAD.ActiveDocument.recompute()
|
||||
return newobj
|
||||
obj = FreeCAD.ActiveDocument.addObject("Part::Part2DObjectPython","Ellipse")
|
||||
_Ellipse(obj)
|
||||
obj.MajorRadius = majradius
|
||||
obj.MinorRadius = minradius
|
||||
obj.Support = support
|
||||
if placement:
|
||||
obj.Placement = placement
|
||||
if gui:
|
||||
_ViewProviderDraft(obj.ViewObject)
|
||||
if not face:
|
||||
obj.ViewObject.DisplayMode = "Wireframe"
|
||||
formatObject(obj)
|
||||
select(obj)
|
||||
return obj
|
||||
|
||||
def extrude(obj,vector):
|
||||
'''makeExtrusion(object,vector): extrudes the given object
|
||||
|
@ -1682,6 +1694,34 @@ def makePoint(X=0, Y=0, Z=0,color=None,name = "Point", point_size= 5):
|
|||
FreeCAD.ActiveDocument.recompute()
|
||||
return obj
|
||||
|
||||
def makeShapeString(String,FontFile,Size = 100,Tracking = 0):
|
||||
'''ShapeString(Text,FontFile,Height,Track): Turns a text string
|
||||
into a Compound Shape'''
|
||||
|
||||
# temporary code
|
||||
import platform
|
||||
if not (platform.system() == 'Linux'):
|
||||
# if (platform.system() == 'Linux'):
|
||||
FreeCAD.Console.PrintWarning("Sorry, ShapeString is not yet implemented for your platform.\n")
|
||||
return (None)
|
||||
# temporary code
|
||||
|
||||
obj = FreeCAD.ActiveDocument.addObject("Part::Part2DObjectPython","ShapeString")
|
||||
_ShapeString(obj)
|
||||
obj.String = String
|
||||
obj.FontFile = FontFile
|
||||
obj.Size = Size
|
||||
obj.Tracking = Tracking
|
||||
|
||||
if gui:
|
||||
_ViewProviderDraft(obj.ViewObject)
|
||||
formatObject(obj)
|
||||
obrep = obj.ViewObject
|
||||
if "PointSize" in obrep.PropertiesList: obrep.PointSize = 1 # hide the segment end points
|
||||
select(obj)
|
||||
FreeCAD.ActiveDocument.recompute()
|
||||
return obj
|
||||
|
||||
def clone(obj,delta=None):
|
||||
'''clone(obj,[delta]): makes a clone of the given object(s). The clone is an exact,
|
||||
linked copy of the given object. If the original object changes, the final object
|
||||
|
@ -3001,6 +3041,36 @@ class _Circle(_DraftObject):
|
|||
fp.Shape = shape
|
||||
fp.Placement = plm
|
||||
|
||||
class _Ellipse(_DraftObject):
|
||||
"The Circle object"
|
||||
|
||||
def __init__(self, obj):
|
||||
_DraftObject.__init__(self,obj,"Ellipse")
|
||||
obj.addProperty("App::PropertyDistance","MinorRadius","Base",
|
||||
"The minor radius of the ellipse")
|
||||
obj.addProperty("App::PropertyDistance","MajorRadius","Base",
|
||||
"The major radius of the ellipse")
|
||||
|
||||
def execute(self, fp):
|
||||
self.createGeometry(fp)
|
||||
|
||||
def onChanged(self, fp, prop):
|
||||
if prop in ["MinorRadius","MajorRadius"]:
|
||||
self.createGeometry(fp)
|
||||
|
||||
def createGeometry(self,fp):
|
||||
import Part
|
||||
plm = fp.Placement
|
||||
if fp.MajorRadius < fp.MinorRadius:
|
||||
msg(translate("Error: Major radius is smaller than the minor radius"))
|
||||
return
|
||||
if fp.MajorRadius and fp.MinorRadius:
|
||||
shape = Part.Ellipse(Vector(0,0,0),fp.MajorRadius,fp.MinorRadius).toShape()
|
||||
shape = Part.Wire(shape)
|
||||
shape = Part.Face(shape)
|
||||
fp.Shape = shape
|
||||
fp.Placement = plm
|
||||
|
||||
class _Wire(_DraftObject):
|
||||
"The Wire object"
|
||||
|
||||
|
@ -3371,45 +3441,9 @@ class _Shape2DView(_DraftObject):
|
|||
if prop in ["Projection","Base","ProjectionMode","FaceNumbers"]:
|
||||
self.createGeometry(obj)
|
||||
|
||||
def clean(self,shape):
|
||||
"returns a valid compound of edges, by recreating them"
|
||||
# this is because the projection algorithm somehow creates wrong shapes.
|
||||
# they dispay fine, but on loading the file the shape is invalid
|
||||
import Part,DraftGeomUtils
|
||||
oldedges = shape.Edges
|
||||
newedges = []
|
||||
for e in oldedges:
|
||||
try:
|
||||
if DraftGeomUtils.geomType(e) == "Line":
|
||||
newedges.append(e.Curve.toShape())
|
||||
elif DraftGeomUtils.geomType(e) == "Circle":
|
||||
if len(e.Vertexes) > 1:
|
||||
mp = DraftGeomUtils.findMidpoint(e)
|
||||
a = Part.Arc(e.Vertexes[0].Point,mp,e.Vertexes[-1].Point).toShape()
|
||||
newedges.append(a)
|
||||
else:
|
||||
newedges.append(e.Curve.toShape())
|
||||
elif DraftGeomUtils.geomType(e) == "Ellipse":
|
||||
if len(e.Vertexes) > 1:
|
||||
a = Part.Arc(e.Curve,e.FirstParameter,e.LastParameter).toShape()
|
||||
newedges.append(a)
|
||||
else:
|
||||
newedges.append(e.Curve.toShape())
|
||||
elif DraftGeomUtils.geomType(e) == "BSplineCurve":
|
||||
if DraftGeomUtils.isLine(e.Curve):
|
||||
l = Part.Line(e.Vertexes[0].Point,e.Vertexes[-1].Point).toShape()
|
||||
newedges.append(l)
|
||||
else:
|
||||
newedges.append(e.Curve.toShape())
|
||||
else:
|
||||
newedges.append(e)
|
||||
except:
|
||||
print "Debug: error cleaning edge ",e
|
||||
return Part.makeCompound(newedges)
|
||||
|
||||
def getProjected(self,obj,shape,direction):
|
||||
"returns projected edges from a shape and a direction"
|
||||
import Part,Drawing
|
||||
import Part,Drawing,DraftGeomUtils
|
||||
edges = []
|
||||
groups = Drawing.projectEx(shape,direction)
|
||||
for g in groups[0:5]:
|
||||
|
@ -3420,7 +3454,7 @@ class _Shape2DView(_DraftObject):
|
|||
for g in groups[5:]:
|
||||
edges.append(g)
|
||||
#return Part.makeCompound(edges)
|
||||
return self.clean(Part.makeCompound(edges))
|
||||
return DraftGeomUtils.cleanProjection(Part.makeCompound(edges))
|
||||
|
||||
def createGeometry(self,obj):
|
||||
import DraftGeomUtils
|
||||
|
@ -3694,6 +3728,91 @@ class _ViewProviderClone(_ViewProviderDraftAlt):
|
|||
def getIcon(self):
|
||||
return ":/icons/Draft_Clone.svg"
|
||||
|
||||
class _ShapeString(_DraftObject):
|
||||
"The ShapeString object"
|
||||
|
||||
def __init__(self, obj):
|
||||
_DraftObject.__init__(self,obj,"ShapeString")
|
||||
obj.addProperty("App::PropertyString","String","Base","Text string")
|
||||
obj.addProperty("App::PropertyString","FontFile","Base","Font file name")
|
||||
obj.addProperty("App::PropertyFloat","Size","Base","Height of text")
|
||||
obj.addProperty("App::PropertyInteger","Tracking","Base",
|
||||
"Inter-character spacing")
|
||||
|
||||
def execute(self, fp):
|
||||
self.createGeometry(fp)
|
||||
|
||||
def onChanged(self, fp, prop):
|
||||
pass
|
||||
|
||||
def createGeometry(self,fp):
|
||||
import Part
|
||||
# import OpenSCAD2Dgeom
|
||||
import os
|
||||
if fp.String and fp.FontFile:
|
||||
if fp.Placement:
|
||||
plm = fp.Placement
|
||||
# TODO: os.path.splitunc() for Win/Samba net files?
|
||||
head, tail = os.path.splitdrive(fp.FontFile) # os.path.splitdrive() for Win
|
||||
head, tail = os.path.split(tail)
|
||||
head = head + '/' # os.split drops last '/' from head
|
||||
CharList = Part.makeWireString(fp.String,
|
||||
head,
|
||||
tail,
|
||||
fp.Size,
|
||||
fp.Tracking)
|
||||
SSChars = []
|
||||
for char in CharList:
|
||||
CharFaces = []
|
||||
for CWire in char:
|
||||
f = Part.Face(CWire)
|
||||
if f:
|
||||
CharFaces.append(f)
|
||||
# whitespace (ex: ' ') has no faces. This breaks OpenSCAD2Dgeom...
|
||||
if CharFaces:
|
||||
# s = OpenSCAD2Dgeom.Overlappingfaces(CharFaces).makeshape()
|
||||
s = self.makeGlyph(CharFaces)
|
||||
SSChars.append(s)
|
||||
shape = Part.Compound(SSChars)
|
||||
fp.Shape = shape
|
||||
if plm:
|
||||
fp.Placement = plm
|
||||
|
||||
def makeGlyph(self, facelist):
|
||||
''' turn list of simple contour faces into a compound shape representing a glyph '''
|
||||
''' remove cuts, fuse overlapping contours, retain islands '''
|
||||
import Part
|
||||
if len(facelist) == 1:
|
||||
return(facelist[0])
|
||||
|
||||
sortedfaces = sorted(facelist,key=(lambda shape: shape.Area),reverse=True)
|
||||
|
||||
biggest = sortedfaces[0]
|
||||
result = biggest
|
||||
islands =[]
|
||||
for face in sortedfaces[1:]:
|
||||
bcfA = biggest.common(face).Area
|
||||
fA = face.Area
|
||||
difA = abs(bcfA - fA)
|
||||
eps = epsilon()
|
||||
# if biggest.common(face).Area == face.Area:
|
||||
if difA <= eps: # close enough to zero
|
||||
# biggest completely overlaps current face ==> cut
|
||||
result = result.cut(face)
|
||||
# elif biggest.common(face).Area == 0:
|
||||
elif bcfA <= eps:
|
||||
# island
|
||||
islands.append(face)
|
||||
else:
|
||||
# partial overlap - (font designer error?)
|
||||
result = result.fuse(face)
|
||||
glyphfaces = [result]
|
||||
glyphfaces.extend(islands)
|
||||
ret = Part.Compound(glyphfaces) # should we fuse these instead of making compound?
|
||||
return ret
|
||||
|
||||
#----End of Python Features Definitions----#
|
||||
|
||||
if gui:
|
||||
if not hasattr(FreeCADGui,"Snapper"):
|
||||
import DraftSnap
|
||||
|
|
|
@ -195,30 +195,13 @@ def findIntersection(edge1,edge2,infinite1=False,infinite2=False,ex1=False,ex2=F
|
|||
returns a list containing the intersection point(s) of 2 edges.
|
||||
You can also feed 4 points instead of edge1 and edge2'''
|
||||
|
||||
pt1 = None
|
||||
|
||||
if isinstance(edge1,FreeCAD.Vector) and isinstance(edge2,FreeCAD.Vector):
|
||||
# we got points directly
|
||||
pt1 = edge1
|
||||
pt2 = edge2
|
||||
pt3 = infinite1
|
||||
pt4 = infinite2
|
||||
infinite1 = ex1
|
||||
infinite2 = ex2
|
||||
|
||||
elif (geomType(edge1) == "Line") and (geomType(edge2) == "Line") :
|
||||
# we have 2 straight lines
|
||||
pt1, pt2, pt3, pt4 = [edge1.Vertexes[0].Point,
|
||||
edge1.Vertexes[1].Point,
|
||||
edge2.Vertexes[0].Point,
|
||||
edge2.Vertexes[1].Point]
|
||||
|
||||
def getLineIntersections(pt1,pt2,pt3,pt4,infinite1,infinite2):
|
||||
if pt1:
|
||||
# first check if we don't already have coincident endpoints
|
||||
if (pt1 in [pt3,pt4]):
|
||||
return [pt1]
|
||||
elif (pt2 in [pt3,pt4]):
|
||||
return [pt2]
|
||||
# first check if we don't already have coincident endpoints
|
||||
if (pt1 in [pt3,pt4]):
|
||||
return [pt1]
|
||||
elif (pt2 in [pt3,pt4]):
|
||||
return [pt2]
|
||||
norm1 = pt2.sub(pt1).cross(pt3.sub(pt1))
|
||||
norm2 = pt2.sub(pt4).cross(pt3.sub(pt4))
|
||||
if not DraftVecUtils.isNull(norm1):
|
||||
|
@ -251,6 +234,26 @@ def findIntersection(edge1,edge2,infinite1=False,infinite2=False,ex1=False,ex2=F
|
|||
else :
|
||||
return [] # Lines aren't on same plane
|
||||
|
||||
pt1 = None
|
||||
|
||||
if isinstance(edge1,FreeCAD.Vector) and isinstance(edge2,FreeCAD.Vector):
|
||||
# we got points directly
|
||||
pt1 = edge1
|
||||
pt2 = edge2
|
||||
pt3 = infinite1
|
||||
pt4 = infinite2
|
||||
infinite1 = ex1
|
||||
infinite2 = ex2
|
||||
return getLineIntersections(pt1,pt2,pt3,pt4,infinite1,infinite2)
|
||||
|
||||
elif (geomType(edge1) == "Line") and (geomType(edge2) == "Line") :
|
||||
# we have 2 straight lines
|
||||
pt1, pt2, pt3, pt4 = [edge1.Vertexes[0].Point,
|
||||
edge1.Vertexes[1].Point,
|
||||
edge2.Vertexes[0].Point,
|
||||
edge2.Vertexes[1].Point]
|
||||
return getLineIntersections(pt1,pt2,pt3,pt4,infinite1,infinite2)
|
||||
|
||||
elif (geomType(edge1) == "Circle") and (geomType(edge2) == "Line") \
|
||||
or (geomType(edge1) == "Line") and (geomType(edge2) == "Circle") :
|
||||
|
||||
|
@ -1668,6 +1671,71 @@ def filletWire(aWire,r,chamfer=False):
|
|||
filEdges[0] = result[2]
|
||||
return Part.Wire(filEdges)
|
||||
|
||||
def getCircleFromSpline(edge):
|
||||
"returns a circle-based edge from a bspline-based edge"
|
||||
if geomType(edge) != "BSplineCurve":
|
||||
return None
|
||||
if len(edge.Vertexes) != 1:
|
||||
return None
|
||||
# get 2 points
|
||||
p1 = edge.Curve.value(0)
|
||||
p2 = edge.Curve.value(math.pi/2)
|
||||
# get 2 tangents
|
||||
t1 = edge.Curve.tangent(0)[0]
|
||||
t2 = edge.Curve.tangent(math.pi/2)[0]
|
||||
# get normal
|
||||
n = p1.cross(p2)
|
||||
if DraftVecUtils.isNull(n):
|
||||
return None
|
||||
# get rays
|
||||
r1 = DraftVecUtils.rotate(t1,math.pi/2,n)
|
||||
r2 = DraftVecUtils.rotate(t2,math.pi/2,n)
|
||||
# get center (intersection of rays)
|
||||
i = findIntersection(p1,p1.add(r1),p2,p2.add(r2),True,True)
|
||||
if not i:
|
||||
return None
|
||||
c = i[0]
|
||||
r = (p1.sub(c)).Length
|
||||
circle = Part.makeCircle(r,c,n)
|
||||
#print circle.Curve
|
||||
return circle
|
||||
|
||||
def cleanProjection(shape):
|
||||
"returns a valid compound of edges, by recreating them"
|
||||
# this is because the projection algorithm somehow creates wrong shapes.
|
||||
# they dispay fine, but on loading the file the shape is invalid
|
||||
oldedges = shape.Edges
|
||||
newedges = []
|
||||
for e in oldedges:
|
||||
try:
|
||||
if geomType(e) == "Line":
|
||||
newedges.append(e.Curve.toShape())
|
||||
elif geomType(e) == "Circle":
|
||||
if len(e.Vertexes) > 1:
|
||||
mp = findMidpoint(e)
|
||||
a = Part.Arc(e.Vertexes[0].Point,mp,e.Vertexes[-1].Point).toShape()
|
||||
newedges.append(a)
|
||||
else:
|
||||
newedges.append(e.Curve.toShape())
|
||||
elif geomType(e) == "Ellipse":
|
||||
if len(e.Vertexes) > 1:
|
||||
a = Part.Arc(e.Curve,e.FirstParameter,e.LastParameter).toShape()
|
||||
newedges.append(a)
|
||||
else:
|
||||
newedges.append(e.Curve.toShape())
|
||||
elif geomType(e) == "BSplineCurve":
|
||||
if isLine(e.Curve):
|
||||
l = Part.Line(e.Vertexes[0].Point,e.Vertexes[-1].Point).toShape()
|
||||
newedges.append(l)
|
||||
else:
|
||||
newedges.append(e.Curve.toShape())
|
||||
else:
|
||||
newedges.append(e)
|
||||
except:
|
||||
print "Debug: error cleaning edge ",e
|
||||
return Part.makeCompound(newedges)
|
||||
|
||||
|
||||
# circle functions *********************************************************
|
||||
|
||||
def getBoundaryAngles(angle,alist):
|
||||
|
|
|
@ -313,6 +313,27 @@ class DraftToolBar:
|
|||
self.zValue.setText("0.00")
|
||||
self.textValue = self._lineedit("textValue", self.layout)
|
||||
|
||||
# shapestring
|
||||
|
||||
self.labelSSize = self._label("labelSize", self.layout)
|
||||
self.SSizeValue = self._lineedit("SSizeValue", self.layout, width=60)
|
||||
self.SSizeValue.setText("200.0")
|
||||
self.labelSTrack = self._label("labelTracking", self.layout)
|
||||
self.STrackValue = self._lineedit("STrackValue", self.layout, width=60)
|
||||
self.STrackValue.setText("0")
|
||||
self.labelSString = self._label("labelString", self.layout)
|
||||
self.SStringValue = self._lineedit("SStringValue", self.layout)
|
||||
self.SStringValue.setText("")
|
||||
self.labelFFile = self._label("labelFFile", self.layout)
|
||||
self.FFileValue = self._lineedit("FFileValue", self.layout)
|
||||
defFile = Draft.getParam("FontFile")
|
||||
if defFile:
|
||||
self.FFileValue.setText(defFile)
|
||||
else:
|
||||
self.FFileValue.setText("")
|
||||
self.chooserButton = self._pushbutton("chooserButton", self.layout, width=26)
|
||||
self.chooserButton.setText("...")
|
||||
|
||||
# options
|
||||
|
||||
self.numFaces = self._spinbox("numFaces", self.layout, 3)
|
||||
|
@ -386,6 +407,19 @@ class DraftToolBar:
|
|||
QtCore.QObject.connect(self.radiusValue,QtCore.SIGNAL("escaped()"),self.escape)
|
||||
QtCore.QObject.connect(self.baseWidget,QtCore.SIGNAL("resized()"),self.relocate)
|
||||
QtCore.QObject.connect(self.baseWidget,QtCore.SIGNAL("retranslate()"),self.retranslateUi)
|
||||
QtCore.QObject.connect(self.SSizeValue,QtCore.SIGNAL("returnPressed()"),self.validateSNumeric)
|
||||
QtCore.QObject.connect(self.SSizeValue,QtCore.SIGNAL("escaped()"),self.escape)
|
||||
QtCore.QObject.connect(self.STrackValue,QtCore.SIGNAL("returnPressed()"),self.validateSNumeric)
|
||||
QtCore.QObject.connect(self.STrackValue,QtCore.SIGNAL("escaped()"),self.escape)
|
||||
QtCore.QObject.connect(self.SStringValue,QtCore.SIGNAL("returnPressed()"),self.validateSString)
|
||||
QtCore.QObject.connect(self.SStringValue,QtCore.SIGNAL("escaped()"),self.escape)
|
||||
QtCore.QObject.connect(self.chooserButton,QtCore.SIGNAL("pressed()"),self.pickFile)
|
||||
QtCore.QObject.connect(self.FFileValue,QtCore.SIGNAL("returnPressed()"),self.validateFile)
|
||||
QtCore.QObject.connect(self.FFileValue,QtCore.SIGNAL("escaped()"),self.escape)
|
||||
|
||||
# if Ui changed to have Size & Track visible at same time, use this
|
||||
# QtCore.QObject.connect(self.SSizeValue,QtCore.SIGNAL("returnPressed()"),self.checkSSize)
|
||||
# QtCore.QObject.connect(self.STrackValue,QtCore.SIGNAL("returnPressed()"),self.checkSTrack)
|
||||
|
||||
def setupTray(self):
|
||||
"sets draft tray buttons up"
|
||||
|
@ -478,6 +512,15 @@ class DraftToolBar:
|
|||
self.resetPlaneButton.setToolTip(translate("draft", "Do not project points to a drawing plane"))
|
||||
self.isCopy.setText(translate("draft", "&Copy"))
|
||||
self.isCopy.setToolTip(translate("draft", "If checked, objects will be copied instead of moved (C)"))
|
||||
self.SStringValue.setToolTip(translate("draft", "Text string to draw"))
|
||||
self.labelSString.setText(translate("draft", "String"))
|
||||
self.SSizeValue.setToolTip(translate("draft", "Height of text"))
|
||||
self.labelSSize.setText(translate("draft", "Height"))
|
||||
self.STrackValue.setToolTip(translate("draft", "Intercharacter spacing"))
|
||||
self.labelSTrack.setText(translate("draft", "Tracking"))
|
||||
self.labelFFile.setText(translate("draft", "Pick a font file"))
|
||||
self.chooserButton.setToolTip(translate("draft", "Open a FileChooser for font file"))
|
||||
|
||||
if (not self.taskmode) or self.tray:
|
||||
self.wplabel.setToolTip(translate("draft", "Set/unset a working plane"))
|
||||
self.colorButton.setToolTip(translate("draft", "Line Color"))
|
||||
|
@ -528,6 +571,15 @@ class DraftToolBar:
|
|||
self.offsetLabel.show()
|
||||
self.offsetValue.show()
|
||||
|
||||
def hideXYZ(self):
|
||||
''' turn off all the point entry widgets '''
|
||||
self.labelx.hide()
|
||||
self.labely.hide()
|
||||
self.labelz.hide()
|
||||
self.xValue.hide()
|
||||
self.yValue.hide()
|
||||
self.zValue.hide()
|
||||
|
||||
def lineUi(self,title=None):
|
||||
if title:
|
||||
self.pointUi(title,icon="Draft_Line")
|
||||
|
@ -606,12 +658,7 @@ class DraftToolBar:
|
|||
else:
|
||||
self.setTitle(translate("draft", "None"))
|
||||
self.labelx.setText(translate("draft", "X"))
|
||||
self.labelx.hide()
|
||||
self.labely.hide()
|
||||
self.labelz.hide()
|
||||
self.xValue.hide()
|
||||
self.yValue.hide()
|
||||
self.zValue.hide()
|
||||
self.hideXYZ()
|
||||
self.numFaces.hide()
|
||||
self.isRelative.hide()
|
||||
self.hasFill.hide()
|
||||
|
@ -634,6 +681,15 @@ class DraftToolBar:
|
|||
self.textValue.hide()
|
||||
self.continueCmd.hide()
|
||||
self.occOffset.hide()
|
||||
self.labelSString.hide()
|
||||
self.SStringValue.hide()
|
||||
self.labelSSize.hide()
|
||||
self.SSizeValue.hide()
|
||||
self.labelSTrack.hide()
|
||||
self.STrackValue.hide()
|
||||
self.labelFFile.hide()
|
||||
self.FFileValue.hide()
|
||||
self.chooserButton.hide()
|
||||
|
||||
def trimUi(self,title=translate("draft","Trim")):
|
||||
self.taskUi(title)
|
||||
|
@ -643,23 +699,13 @@ class DraftToolBar:
|
|||
self.radiusValue.selectAll()
|
||||
|
||||
def radiusUi(self):
|
||||
self.labelx.hide()
|
||||
self.labely.hide()
|
||||
self.labelz.hide()
|
||||
self.xValue.hide()
|
||||
self.yValue.hide()
|
||||
self.zValue.hide()
|
||||
self.hideXYZ()
|
||||
self.labelRadius.setText(translate("draft", "Radius"))
|
||||
self.labelRadius.show()
|
||||
self.radiusValue.show()
|
||||
|
||||
def textUi(self):
|
||||
self.labelx.hide()
|
||||
self.labely.hide()
|
||||
self.labelz.hide()
|
||||
self.xValue.hide()
|
||||
self.yValue.hide()
|
||||
self.zValue.hide()
|
||||
self.hideXYZ()
|
||||
self.textValue.show()
|
||||
self.textValue.setText('')
|
||||
self.textValue.setFocus()
|
||||
|
@ -667,6 +713,43 @@ class DraftToolBar:
|
|||
self.textline=0
|
||||
self.continueCmd.show()
|
||||
|
||||
def SSUi(self):
|
||||
''' set up ui for ShapeString text entry '''
|
||||
self.hideXYZ()
|
||||
self.labelSString.show()
|
||||
self.SStringValue.show()
|
||||
self.SStringValue.setText('')
|
||||
self.SStringValue.setFocus()
|
||||
self.continueCmd.hide()
|
||||
|
||||
def SSizeUi(self):
|
||||
''' set up ui for ShapeString size entry '''
|
||||
self.labelSString.hide()
|
||||
self.SStringValue.hide()
|
||||
self.continueCmd.hide()
|
||||
self.labelSSize.show()
|
||||
self.SSizeValue.setText('200.0')
|
||||
self.SSizeValue.show()
|
||||
self.SSizeValue.setFocus()
|
||||
|
||||
def STrackUi(self):
|
||||
''' set up ui for ShapeString tracking entry '''
|
||||
self.labelSSize.hide()
|
||||
self.SSizeValue.hide()
|
||||
self.labelSTrack.show()
|
||||
self.STrackValue.setText('0')
|
||||
self.STrackValue.show()
|
||||
self.STrackValue.setFocus()
|
||||
|
||||
def SFileUi(self):
|
||||
''' set up UI for ShapeString font file selection '''
|
||||
self.labelSTrack.hide()
|
||||
self.STrackValue.hide()
|
||||
self.labelFFile.show()
|
||||
self.FFileValue.show()
|
||||
self.chooserButton.show()
|
||||
self.FFileValue.setFocus()
|
||||
|
||||
def switchUi(self,store=True):
|
||||
if store:
|
||||
self.state = []
|
||||
|
@ -676,12 +759,7 @@ class DraftToolBar:
|
|||
self.state.append(self.xValue.isVisible())
|
||||
self.state.append(self.yValue.isVisible())
|
||||
self.state.append(self.zValue.isVisible())
|
||||
self.labelx.hide()
|
||||
self.labely.hide()
|
||||
self.labelz.hide()
|
||||
self.xValue.hide()
|
||||
self.yValue.hide()
|
||||
self.zValue.hide()
|
||||
self.hideXYZ()
|
||||
else:
|
||||
if self.state:
|
||||
if self.state[0]:self.labelx.show()
|
||||
|
@ -707,12 +785,7 @@ class DraftToolBar:
|
|||
|
||||
def editUi(self):
|
||||
self.taskUi(translate("draft", "Edit"))
|
||||
self.labelx.hide()
|
||||
self.labely.hide()
|
||||
self.labelz.hide()
|
||||
self.xValue.hide()
|
||||
self.yValue.hide()
|
||||
self.zValue.hide()
|
||||
self.hideXYZ()
|
||||
self.numFaces.hide()
|
||||
self.isRelative.hide()
|
||||
self.hasFill.hide()
|
||||
|
@ -902,6 +975,74 @@ class DraftToolBar:
|
|||
numz = last.z + v.z
|
||||
self.sourceCmd.numericInput(numx,numy,numz)
|
||||
|
||||
def validateSNumeric(self):
|
||||
''' send valid numeric parameters to ShapeString '''
|
||||
if self.sourceCmd:
|
||||
if (self.labelSSize.isVisible()):
|
||||
try:
|
||||
SSize=float(self.SSizeValue.text())
|
||||
except ValueError:
|
||||
FreeCAD.Console.PrintMessage(translate("draft", "Invalid Size value. Using 200.0."))
|
||||
self.sourceCmd.numericSSize(unicode("200.0"))
|
||||
else:
|
||||
self.sourceCmd.numericSSize(unicode(SSize))
|
||||
elif (self.labelSTrack.isVisible()):
|
||||
try:
|
||||
track=int(self.STrackValue.text())
|
||||
except ValueError:
|
||||
FreeCAD.Console.PrintMessage(translate("draft", "Invalid Tracking value. Using 0."))
|
||||
self.sourceCmd.numericSTrack(unicode("0"))
|
||||
else:
|
||||
self.sourceCmd.numericSTrack(unicode(track))
|
||||
|
||||
def validateSString(self):
|
||||
''' send a valid text string to ShapeString as unicode '''
|
||||
if self.sourceCmd:
|
||||
if (self.labelSString.isVisible()):
|
||||
if self.SStringValue.text():
|
||||
# print "debug: D_G DraftToolBar.validateSString type(SStringValue.text): " str(type(self.SStringValue.text))
|
||||
self.sourceCmd.validSString(str(self.SStringValue.text().toUtf8())) # QString to QByteArray to PyString
|
||||
else:
|
||||
FreeCAD.Console.PrintMessage(translate("draft", "Please enter a text string."))
|
||||
|
||||
|
||||
def pickFile(self):
|
||||
''' invoke a font file chooser dialog and send result to ShapeString to'''
|
||||
if self.sourceCmd:
|
||||
if (self.chooserButton.isVisible()):
|
||||
try:
|
||||
dialogCaption = translate("draft", "Select a Font file")
|
||||
dialogDir = os.path.dirname(Draft.getParam("FontFile"))
|
||||
if not dialogDir:
|
||||
dialogDir = os.getcwd() # reasonable default?
|
||||
dialogFilter = "Fonts (*.ttf *.pfb *.otf);;All files (*.*)"
|
||||
fname = QtGui.QFileDialog.getOpenFileName(self.baseWidget,
|
||||
dialogCaption,
|
||||
dialogDir,
|
||||
dialogFilter)
|
||||
fname = str(fname.toUtf8()) # QString to PyString
|
||||
# print "debug: D_G DraftToolBar.pickFile type(fname): " str(type(fname))
|
||||
|
||||
except Exception as e:
|
||||
FreeCAD.Console.PrintMessage("DraftGui.pickFile: unable to select a font file.")
|
||||
print type(e)
|
||||
print e.args
|
||||
else:
|
||||
if fname:
|
||||
self.sourceCmd.validFFile(fname)
|
||||
else:
|
||||
FreeCAD.Console.PrintMessage("DraftGui.pickFile: no file selected.") # can this happen?
|
||||
|
||||
def validateFile(self):
|
||||
''' check and send font file parameter to ShapeString as unicode'''
|
||||
if self.sourceCmd:
|
||||
if (self.labelFFile.isVisible()):
|
||||
if self.FFileValue.text():
|
||||
self.sourceCmd.validFFile(str(self.FFileValue.text().toUtf8())) #QString to PyString
|
||||
else:
|
||||
FreeCAD.Console.PrintMessage(translate("draft", "Please enter a font file."))
|
||||
|
||||
|
||||
def finish(self):
|
||||
"finish button action"
|
||||
if self.sourceCmd:
|
||||
|
@ -1222,7 +1363,8 @@ class DraftToolBar:
|
|||
self.commands = ["Draft_Line","Draft_Wire",
|
||||
"Draft_Rectangle","Draft_Arc",
|
||||
"Draft_Circle","Draft_BSpline",
|
||||
"Draft_Text","Draft_Dimension"]
|
||||
"Draft_Text","Draft_Dimension",
|
||||
"Draft_ShapeString"]
|
||||
self.title = "Create objects"
|
||||
def shouldShow(self):
|
||||
return (FreeCAD.ActiveDocument != None) and (not FreeCADGui.Selection.getSelection())
|
||||
|
|
|
@ -104,13 +104,14 @@ class Snapper:
|
|||
'ortho':':/icons/Snap_Ortho.svg',
|
||||
'intersection':':/icons/Snap_Intersection.svg'}
|
||||
|
||||
def snap(self,screenpos,lastpoint=None,active=True,constrain=False):
|
||||
"""snap(screenpos,lastpoint=None,active=True,constrain=False): returns a snapped
|
||||
def snap(self,screenpos,lastpoint=None,active=True,constrain=False,noTracker=False):
|
||||
"""snap(screenpos,lastpoint=None,active=True,constrain=False,noTracker=False): returns a snapped
|
||||
point from the given (x,y) screenpos (the position of the mouse cursor), active is to
|
||||
activate active point snapping or not (passive), lastpoint is an optional
|
||||
other point used to draw an imaginary segment and get additional snap locations. Constrain can
|
||||
be True to constrain the point against the closest working plane axis.
|
||||
Screenpos can be a list, a tuple or a coin.SbVec2s object."""
|
||||
Screenpos can be a list, a tuple or a coin.SbVec2s object. If noTracker is True,
|
||||
the tracking line is not displayed."""
|
||||
|
||||
global Part, DraftGeomUtils
|
||||
import Part, DraftGeomUtils
|
||||
|
@ -196,7 +197,7 @@ class Snapper:
|
|||
if active:
|
||||
point = self.snapToGrid(point)
|
||||
fp = cstr(point)
|
||||
if self.trackLine and lastpoint:
|
||||
if self.trackLine and lastpoint and (not noTracker):
|
||||
self.trackLine.p2(fp)
|
||||
self.trackLine.on()
|
||||
return fp
|
||||
|
|
|
@ -121,14 +121,15 @@ def selectObject(arg):
|
|||
FreeCAD.activeDraftCommand.component=snapped['Component']
|
||||
FreeCAD.activeDraftCommand.proceed()
|
||||
|
||||
def getPoint(target,args,mobile=False,sym=False,workingplane=True):
|
||||
def getPoint(target,args,mobile=False,sym=False,workingplane=True,noTracker=False):
|
||||
'''
|
||||
Function used by the Draft Tools.
|
||||
returns a constrained 3d point and its original point.
|
||||
if mobile=True, the constraining occurs from the location of
|
||||
mouse cursor when Shift is pressed, otherwise from last entered
|
||||
point. If sym=True, x and y values stay always equal. If workingplane=False,
|
||||
the point wont be projected on the Working Plane.
|
||||
the point wont be projected on the Working Plane. if noTracker is True, the
|
||||
tracking line will not be displayed
|
||||
'''
|
||||
|
||||
ui = FreeCADGui.draftToolBar
|
||||
|
@ -141,7 +142,7 @@ def getPoint(target,args,mobile=False,sym=False,workingplane=True):
|
|||
last = None
|
||||
amod = hasMod(args,MODSNAP)
|
||||
cmod = hasMod(args,MODCONSTRAIN)
|
||||
point = FreeCADGui.Snapper.snap(args["Position"],lastpoint=last,active=amod,constrain=cmod)
|
||||
point = FreeCADGui.Snapper.snap(args["Position"],lastpoint=last,active=amod,constrain=cmod,noTracker=noTracker)
|
||||
info = FreeCADGui.Snapper.snapInfo
|
||||
ctrlPoint = Vector(point)
|
||||
mask = FreeCADGui.Snapper.affinity
|
||||
|
@ -606,7 +607,7 @@ class BSpline(Line):
|
|||
if arg["Key"] == "ESCAPE":
|
||||
self.finish()
|
||||
elif arg["Type"] == "SoLocation2Event": #mouse movement detection
|
||||
self.point,ctrlPoint,info = getPoint(self,arg)
|
||||
self.point,ctrlPoint,info = getPoint(self,arg,noTracker=True)
|
||||
self.bsplinetrack.update(self.node + [self.point])
|
||||
elif arg["Type"] == "SoMouseButtonEvent":
|
||||
if (arg["State"] == "DOWN") and (arg["Button"] == "BUTTON1"):
|
||||
|
@ -813,7 +814,7 @@ class Rectangle(Creator):
|
|||
if arg["Key"] == "ESCAPE":
|
||||
self.finish()
|
||||
elif arg["Type"] == "SoLocation2Event": #mouse movement detection
|
||||
self.point,ctrlPoint,info = getPoint(self,arg,mobile=True)
|
||||
self.point,ctrlPoint,info = getPoint(self,arg,mobile=True,noTracker=True)
|
||||
self.rect.update(self.point)
|
||||
elif arg["Type"] == "SoMouseButtonEvent":
|
||||
if (arg["State"] == "DOWN") and (arg["Button"] == "BUTTON1"):
|
||||
|
@ -1394,7 +1395,7 @@ class Ellipse(Creator):
|
|||
'pl = FreeCAD.Placement()',
|
||||
'pl.Rotation.Q='+rot,
|
||||
'pl.Base = '+DraftVecUtils.toString(center),
|
||||
'Draft.makeEllipse('+str(r1)+','+str(r2)+',placement=pl)'])
|
||||
'Draft.makeEllipse('+str(r1)+','+str(r2)+',placement=pl,face='+fil+',support='+sup+')'])
|
||||
except:
|
||||
print "Draft: Error: Unable to create object."
|
||||
self.finish(cont=True)
|
||||
|
@ -1405,7 +1406,7 @@ class Ellipse(Creator):
|
|||
if arg["Key"] == "ESCAPE":
|
||||
self.finish()
|
||||
elif arg["Type"] == "SoLocation2Event": #mouse movement detection
|
||||
self.point,ctrlPoint,info = getPoint(self,arg,mobile=True)
|
||||
self.point,ctrlPoint,info = getPoint(self,arg,mobile=True,noTracker=True)
|
||||
self.rect.update(self.point)
|
||||
elif arg["Type"] == "SoMouseButtonEvent":
|
||||
if (arg["State"] == "DOWN") and (arg["Button"] == "BUTTON1"):
|
||||
|
@ -1616,8 +1617,9 @@ class Dimension(Creator):
|
|||
if arg["Key"] == "ESCAPE":
|
||||
self.finish()
|
||||
elif arg["Type"] == "SoLocation2Event": #mouse movement detection
|
||||
import DraftGeomUtils
|
||||
shift = hasMod(arg,MODCONSTRAIN)
|
||||
self.point,ctrlPoint,self.info = getPoint(self,arg)
|
||||
self.point,ctrlPoint,self.info = getPoint(self,arg,noTracker=(len(self.node)>0))
|
||||
if self.arcmode or self.point2:
|
||||
setMod(arg,MODCONSTRAIN,False)
|
||||
if hasMod(arg,MODALT) and (len(self.node)<3):
|
||||
|
@ -1696,6 +1698,7 @@ class Dimension(Creator):
|
|||
self.dimtrack.update(self.node+[self.point]+[self.cont])
|
||||
elif arg["Type"] == "SoMouseButtonEvent":
|
||||
if (arg["State"] == "DOWN") and (arg["Button"] == "BUTTON1"):
|
||||
import DraftGeomUtils
|
||||
if self.point:
|
||||
if (not self.node) and (not self.support):
|
||||
self.support = getSupport(arg)
|
||||
|
@ -1721,7 +1724,6 @@ class Dimension(Creator):
|
|||
self.node = [v1,v2]
|
||||
self.link = [ob,i1,i2]
|
||||
self.edges.append(ed)
|
||||
import DraftGeomUtils
|
||||
if DraftGeomUtils.geomType(ed) == "Circle":
|
||||
# snapped edge is an arc
|
||||
self.arcmode = "diameter"
|
||||
|
@ -1736,6 +1738,7 @@ class Dimension(Creator):
|
|||
self.node[3],
|
||||
True,True)
|
||||
if c:
|
||||
print "centers:",c
|
||||
self.center = c[0]
|
||||
self.arctrack.setCenter(self.center)
|
||||
self.arctrack.on()
|
||||
|
@ -1786,6 +1789,118 @@ class Dimension(Creator):
|
|||
self.createObject()
|
||||
if not self.cont: self.finish()
|
||||
|
||||
class ShapeString(Creator):
|
||||
"This class creates a shapestring feature."
|
||||
|
||||
def GetResources(self):
|
||||
return {'Pixmap' : 'Draft_ShapeString',
|
||||
'Accel' : "S, S",
|
||||
'MenuShapeString': QtCore.QT_TRANSLATE_NOOP("Draft_ShapeString", "ShapeString"),
|
||||
'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_ShapeString", "Creates text string in shapes.")}
|
||||
|
||||
def Activated(self):
|
||||
name = str(translate("draft","ShapeString"))
|
||||
Creator.Activated(self,name)
|
||||
if self.ui:
|
||||
self.ui.sourceCmd = self
|
||||
self.dialog = None
|
||||
self.text = ''
|
||||
self.ui.sourceCmd = self
|
||||
self.ui.pointUi(name)
|
||||
self.call = self.view.addEventCallback("SoEvent",self.action)
|
||||
self.ui.xValue.setFocus()
|
||||
self.ui.xValue.selectAll()
|
||||
msg(translate("draft", "Pick ShapeString location point:\n"))
|
||||
FreeCADGui.draftToolBar.show()
|
||||
|
||||
def createObject(self):
|
||||
"creates object in the current doc"
|
||||
# print "debug: D_T ShapeString.createObject type(self.SString): " str(type(self.SString))
|
||||
# temporary code
|
||||
import platform
|
||||
if not (platform.system() == 'Linux'):
|
||||
# if (platform.system() == 'Linux'):
|
||||
FreeCAD.Console.PrintWarning("Sorry, ShapeString is not yet fully implemented for your platform.\n")
|
||||
self.finish()
|
||||
return
|
||||
# temporary code
|
||||
|
||||
dquote = '"'
|
||||
String = dquote + self.SString + dquote
|
||||
Size = str(self.SSSize) # numbers are ascii so this should always work
|
||||
Tracking = str(self.SSTrack) # numbers are ascii so this should always work
|
||||
FFile = dquote + self.FFile + dquote
|
||||
# print "debug: D_T ShapeString.createObject type(String): " str(type(String))
|
||||
# print "debug: D_T ShapeString.createObject type(FFile): " str(type(FFile))
|
||||
|
||||
try:
|
||||
qr,sup,points,fil = self.getStrings()
|
||||
self.commit(translate("draft","Create ShapeString"),
|
||||
['import Draft',
|
||||
'ss=Draft.makeShapeString(String='+String+',FontFile='+FFile+',Size='+Size+',Tracking='+Tracking+')',
|
||||
'plm=FreeCAD.Placement()',
|
||||
'plm.Base='+DraftVecUtils.toString(self.point),
|
||||
'plm.Rotation.Q='+qr,
|
||||
'ss.Placement=plm',
|
||||
'ss.Support='+sup])
|
||||
except Exception as e:
|
||||
msg("Draft_ShapeString: error delaying commit", "error")
|
||||
print type(e)
|
||||
print e.args
|
||||
self.finish()
|
||||
|
||||
def action(self,arg):
|
||||
"scene event handler"
|
||||
if arg["Type"] == "SoKeyboardEvent":
|
||||
if arg["Key"] == "ESCAPE":
|
||||
self.finish()
|
||||
elif arg["Type"] == "SoLocation2Event": #mouse movement detection
|
||||
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.ui.SSUi()
|
||||
|
||||
def numericInput(self,numx,numy,numz):
|
||||
'''this function gets called by the toolbar when valid
|
||||
x, y, and z have been entered there'''
|
||||
self.point = Vector(numx,numy,numz)
|
||||
self.node.append(self.point)
|
||||
self.ui.SSUi() #move on to next step in parameter entry
|
||||
|
||||
def numericSSize(self,ssize):
|
||||
'''this function is called by the toolbar when valid size parameter
|
||||
has been entered. '''
|
||||
self.SSSize = ssize
|
||||
self.ui.STrackUi()
|
||||
|
||||
def numericSTrack(self,strack):
|
||||
'''this function is called by the toolbar when valid size parameter
|
||||
has been entered. ?'''
|
||||
self.SSTrack = strack
|
||||
self.ui.SFileUi()
|
||||
|
||||
def validSString(self,sstring):
|
||||
'''this function is called by the toolbar when a ?valid? string parameter
|
||||
has been entered. '''
|
||||
self.SString = sstring
|
||||
self.ui.SSizeUi()
|
||||
|
||||
def validFFile(self,FFile):
|
||||
'''this function is called by the toolbar when a ?valid? font file parameter
|
||||
has been entered. '''
|
||||
self.FFile = FFile
|
||||
# last step in ShapeString parm capture, create object
|
||||
self.createObject()
|
||||
|
||||
def finish(self, finishbool=False):
|
||||
"terminates the operation"
|
||||
Creator.finish(self)
|
||||
if self.ui:
|
||||
# del self.dialog # what does this do??
|
||||
if self.ui.continueMode:
|
||||
self.Activated()
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Modifier functions
|
||||
|
@ -1821,7 +1936,14 @@ class Move(Modifier):
|
|||
def proceed(self):
|
||||
if self.call: self.view.removeEventCallback("SoEvent",self.call)
|
||||
self.sel = Draft.getSelection()
|
||||
self.sel = Draft.getGroupContents(self.sel)
|
||||
# testing for special case: only Arch groups in selection
|
||||
onlyarchgroups = True
|
||||
for o in self.sel:
|
||||
if not(Draft.getType(o) in ["Floor","Building","Site"]):
|
||||
onlyarchgroups = False
|
||||
if not onlyarchgroups:
|
||||
# arch groups can be moved, no need to add their children
|
||||
self.sel = Draft.getGroupContents(self.sel)
|
||||
self.ui.pointUi(self.name)
|
||||
self.ui.modUi()
|
||||
self.ui.xValue.setFocus()
|
||||
|
@ -2972,7 +3094,8 @@ class Edit(Modifier):
|
|||
Modifier.finish(self)
|
||||
plane.restore()
|
||||
self.running = False
|
||||
FreeCADGui.ActiveDocument.resetEdit()
|
||||
# following line causes crash
|
||||
# FreeCADGui.ActiveDocument.resetEdit()
|
||||
|
||||
def action(self,arg):
|
||||
"scene event handler"
|
||||
|
@ -3584,6 +3707,7 @@ FreeCADGui.addCommand('Draft_Polygon',Polygon())
|
|||
FreeCADGui.addCommand('Draft_BSpline',BSpline())
|
||||
FreeCADGui.addCommand('Draft_Point',Point())
|
||||
FreeCADGui.addCommand('Draft_Ellipse',Ellipse())
|
||||
FreeCADGui.addCommand('Draft_ShapeString',ShapeString())
|
||||
|
||||
# modification commands
|
||||
FreeCADGui.addCommand('Draft_Move',Move())
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -104,7 +104,8 @@ class DraftWorkbench (Workbench):
|
|||
pass
|
||||
self.cmdList = ["Draft_Line","Draft_Wire","Draft_Circle","Draft_Arc","Draft_Ellipse",
|
||||
"Draft_Polygon","Draft_Rectangle", "Draft_Text",
|
||||
"Draft_Dimension", "Draft_BSpline","Draft_Point"]
|
||||
"Draft_Dimension", "Draft_BSpline","Draft_Point",
|
||||
"Draft_ShapeString"]
|
||||
self.modList = ["Draft_Move","Draft_Rotate","Draft_Offset",
|
||||
"Draft_Trimex", "Draft_Upgrade", "Draft_Downgrade", "Draft_Scale",
|
||||
"Draft_Drawing","Draft_Edit","Draft_WireToBSpline","Draft_AddPoint",
|
||||
|
@ -161,3 +162,12 @@ App.addExportType("Autodesk DXF (*.dxf)","importDXF")
|
|||
App.addExportType("Flattened SVG (*.svg)","importSVG")
|
||||
App.addExportType("Open CAD Format (*.oca)","importOCA")
|
||||
|
||||
# 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")))
|
||||
|
||||
|
|
|
@ -55,6 +55,7 @@
|
|||
<file>icons/Draft_Clone.svg</file>
|
||||
<file>icons/Draft_Heal.svg</file>
|
||||
<file>icons/Draft_Ellipse.svg</file>
|
||||
<file>icons/Draft_ShapeString.svg</file>
|
||||
<file>patterns/concrete.svg</file>
|
||||
<file>patterns/cross.svg</file>
|
||||
<file>patterns/line.svg</file>
|
||||
|
|
112
src/Mod/Draft/Resources/icons/Draft_ShapeString.svg
Normal file
112
src/Mod/Draft/Resources/icons/Draft_ShapeString.svg
Normal file
|
@ -0,0 +1,112 @@
|
|||
<?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:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="64px"
|
||||
height="64px"
|
||||
id="svg4594"
|
||||
sodipodi:version="0.32"
|
||||
inkscape:version="0.48.3.1 r9886"
|
||||
sodipodi:docname="Draft_ShapeString.svg"
|
||||
inkscape:output_extension="org.inkscape.output.svg.inkscape"
|
||||
version="1.1">
|
||||
<defs
|
||||
id="defs4596">
|
||||
<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="perspective4602" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="5.6568542"
|
||||
inkscape:cx="16.724718"
|
||||
inkscape:cy="24.831907"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
inkscape:document-units="px"
|
||||
inkscape:grid-bbox="true"
|
||||
inkscape:window-width="1366"
|
||||
inkscape:window-height="695"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="24"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata4599">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
id="layer1"
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer">
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
|
||||
x="15.684914"
|
||||
y="19.773684"
|
||||
id="text3097"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan3099"
|
||||
x="15.684914"
|
||||
y="19.773684" /></text>
|
||||
<g
|
||||
id="g4061">
|
||||
<text
|
||||
transform="scale(1.2630773,0.79171719)"
|
||||
sodipodi:linespacing="125%"
|
||||
id="text3892"
|
||||
y="69.508385"
|
||||
x="5.465425"
|
||||
style="font-size:77.39546203999999818px;font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;opacity:0.62711863999999995;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:3.191;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;font-family:Times New Roman;-inkscape-font-specification:'Times New Roman, Italic'"
|
||||
xml:space="preserve"><tspan
|
||||
style="stroke-width:3.191;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
y="69.508385"
|
||||
x="5.465425"
|
||||
id="tspan3894"
|
||||
sodipodi:role="line">S</tspan><tspan
|
||||
style="stroke-width:3.191;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
id="tspan3896"
|
||||
y="166.25272"
|
||||
x="5.465425"
|
||||
sodipodi:role="line" /></text>
|
||||
<text
|
||||
inkscape:transform-center-y="17.646795"
|
||||
inkscape:transform-center-x="1.9859923"
|
||||
transform="scale(1.258685,0.79447996)"
|
||||
sodipodi:linespacing="125%"
|
||||
id="text3103"
|
||||
y="65.225639"
|
||||
x="2.1774669"
|
||||
style="font-size:80.06713104px;font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#ffda04;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.57333159;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;font-family:Times New Roman;-inkscape-font-specification:'Times New Roman, Italic'"
|
||||
xml:space="preserve"><tspan
|
||||
style="stroke-width:1.57333159"
|
||||
y="65.225639"
|
||||
x="2.1774669"
|
||||
id="tspan3105"
|
||||
sodipodi:role="line">S</tspan></text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 4.6 KiB |
|
@ -6,8 +6,8 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>590</width>
|
||||
<height>632</height>
|
||||
<width>718</width>
|
||||
<height>808</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
|
@ -1199,6 +1199,49 @@ such as "Arial:Bold"</string>
|
|||
</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>
|
||||
|
|
|
@ -280,6 +280,26 @@ If color mapping is choosed, you must choose a color mapping file containing a t
|
|||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_14">
|
||||
<item>
|
||||
<widget class="Gui::PrefCheckBox" name="gui::prefcheckbox_12">
|
||||
<property name="toolTip">
|
||||
<string>If this is checked, the exported objects will be projected to reflect the current view direction</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Project exported objects along current view direction</string>
|
||||
</property>
|
||||
<property name="prefEntry" stdset="0">
|
||||
<cstring>dxfproject</cstring>
|
||||
</property>
|
||||
<property name="prefPath" stdset="0">
|
||||
<cstring>Mod/Draft</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_11">
|
||||
<item>
|
||||
|
|
94
src/Mod/Draft/importDWG.py
Normal file
94
src/Mod/Draft/importDWG.py
Normal file
|
@ -0,0 +1,94 @@
|
|||
# -*- coding: utf8 -*-
|
||||
|
||||
#***************************************************************************
|
||||
#* *
|
||||
#* Copyright (c) 2009 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 (GPL) *
|
||||
#* 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 *
|
||||
#* *
|
||||
#***************************************************************************
|
||||
|
||||
"FreeCAD Draft Workbench - DWG importer/exporter"
|
||||
|
||||
if open.__module__ == '__builtin__':
|
||||
pythonopen = open # to distinguish python built-in open function from the one declared here
|
||||
|
||||
def open(filename):
|
||||
"called when freecad opens a file."
|
||||
dxf = convertToDxf(filename)
|
||||
import importDXF
|
||||
doc = importDXF.open(dxf)
|
||||
return doc
|
||||
|
||||
def insert(filename,docname):
|
||||
"called when freecad imports a file"
|
||||
dxf = convertToDxf(filemname)
|
||||
import importDXF
|
||||
doc = importDXF.insert(dxf,docname)
|
||||
return doc
|
||||
|
||||
def export(objectslist,filename):
|
||||
"called when freecad exports a file"
|
||||
import importDXF,os,tempfile
|
||||
outdir = tempfile.mkdtemp()
|
||||
dxf = outdir + os.sep + os.path.splitext(os.path.basename(filename))[0] + ".dxf"
|
||||
importDXF.export(objectslist,dxf)
|
||||
convertToDwg(dxf,filename)
|
||||
return filename
|
||||
|
||||
def getTeighaConverter():
|
||||
"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
|
||||
if teigha:
|
||||
if os.path.exists(teigha):
|
||||
return teigha
|
||||
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"
|
||||
|
||||
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
|
|
@ -1190,18 +1190,31 @@ def insert(filename,docname):
|
|||
|
||||
# EXPORT ########################################################################
|
||||
|
||||
def projectShape(shape,direction):
|
||||
import Drawing
|
||||
edges = []
|
||||
try:
|
||||
groups = Drawing.projectEx(shape,direction)
|
||||
except:
|
||||
print "unable to project shape"
|
||||
return shape
|
||||
else:
|
||||
for g in groups[0:5]:
|
||||
if g:
|
||||
edges.append(g)
|
||||
return DraftGeomUtils.cleanProjection(Part.makeCompound(edges))
|
||||
|
||||
def getArcData(edge):
|
||||
"returns center, radius, start and end angles of a circle-based edge"
|
||||
ce = edge.Curve.Center
|
||||
radius = edge.Curve.Radius
|
||||
if len(edge.Vertexes) == 1:
|
||||
# closed circle
|
||||
return ce, radius, 0, 0
|
||||
return DraftVecUtils.tup(ce), radius, 0, 0
|
||||
else:
|
||||
# find direction of arc
|
||||
tang1 = edge.Curve.tangent(edge.ParameterRange[0])
|
||||
tang2 = edge.Curve.tangent(edge.ParameterRange[1])
|
||||
|
||||
# method 1 - find direction of arc from tangents - not reliable
|
||||
#tang1 = edge.Curve.tangent(edge.ParameterRange[0])
|
||||
#tang2 = edge.Curve.tangent(edge.ParameterRange[1])
|
||||
# following code doesn't seem to give right result?
|
||||
# cross1 = Vector.cross(Vector(tang1[0][0],tang1[0][1],tang1[0][2]),Vector(tang2[0][0],tang2[0][1],tang2[0][2]))
|
||||
# if cross1[2] > 0: # >0 ccw <0 cw
|
||||
|
@ -1211,15 +1224,31 @@ def getArcData(edge):
|
|||
# ve1 = edge.Vertexes[-1].Point
|
||||
# ve2 = edge.Vertexes[0].Point
|
||||
|
||||
# check the midpoint seems more reliable
|
||||
# method 3 - recreate an arc and check if the length is the same
|
||||
ve1 = edge.Vertexes[0].Point
|
||||
ve2 = edge.Vertexes[-1].Point
|
||||
ang1 = -math.degrees(DraftVecUtils.angle(ve1.sub(ce)))
|
||||
ang2 = -math.degrees(DraftVecUtils.angle(ve2.sub(ce)))
|
||||
ve3 = DraftGeomUtils.findMidpoint(edge)
|
||||
ang3 = -math.degrees(DraftVecUtils.angle(ve3.sub(ce)))
|
||||
if (ang3 < ang1) and (ang2 < ang3):
|
||||
|
||||
a1 = -DraftVecUtils.angle(ve1.sub(ce))
|
||||
a2 = -DraftVecUtils.angle(ve2.sub(ce))
|
||||
pseudoarc = Part.ArcOfCircle(edge.Curve,a1,a2).toShape()
|
||||
if round(pseudoarc.Length,Draft.precision()) != round(edge.Length,Draft.precision()):
|
||||
ang1, ang2 = ang2, ang1
|
||||
|
||||
# method 2 - check the midpoint - not reliable either
|
||||
#ve3 = DraftGeomUtils.findMidpoint(edge)
|
||||
#ang3 = -math.degrees(DraftVecUtils.angle(ve3.sub(ce)))
|
||||
#print "edge ",edge.hashCode()," data ",ang1, " , ",ang2," , ", ang3
|
||||
#if (ang3 < ang1) and (ang2 < ang3):
|
||||
# print "inverting, case1"
|
||||
# ang1, ang2 = ang2, ang1
|
||||
#elif (ang3 > ang1) and (ang3 > ang2):
|
||||
# print "inverting, case2"
|
||||
# ang1, ang2 = ang2, ang1
|
||||
#elif (ang3 < ang1) and (ang3 < ang2):
|
||||
# print "inverting, case3"
|
||||
# ang1, ang2 = ang2, ang1
|
||||
return DraftVecUtils.tup(ce), radius, ang1, ang2
|
||||
|
||||
def getSplineSegs(edge):
|
||||
|
@ -1246,6 +1275,7 @@ def getWire(wire,nospline=False):
|
|||
"returns an array of dxf-ready points and bulges from a wire"
|
||||
edges = DraftGeomUtils.sortEdges(wire.Edges)
|
||||
points = []
|
||||
# print "processing wire ",wire.Edges
|
||||
for edge in edges:
|
||||
v1 = edge.Vertexes[0].Point
|
||||
if len(edge.Vertexes) < 2:
|
||||
|
@ -1256,7 +1286,8 @@ def getWire(wire,nospline=False):
|
|||
c = edge.Curve.Center
|
||||
angle = abs(DraftVecUtils.angle(v1.sub(c),v2.sub(c)))
|
||||
if DraftGeomUtils.isWideAngle(edge):
|
||||
angle = math.pi*2 - angle
|
||||
if angle < math.pi:
|
||||
angle = math.pi*2 - angle
|
||||
# if (DraftVecUtils.angle(v2.sub(c)) < DraftVecUtils.angle(v1.sub(c))):
|
||||
# angle = -angle
|
||||
# polyline bulge -> negative makes the arc go clockwise
|
||||
|
@ -1293,16 +1324,16 @@ def getWire(wire,nospline=False):
|
|||
# print "wire verts: ",points
|
||||
return points
|
||||
|
||||
def getBlock(obj):
|
||||
def getBlock(sh,obj):
|
||||
"returns a dxf block with the contents of the object"
|
||||
block = dxfLibrary.Block(name=obj.Name,layer=getGroup(obj,exportList))
|
||||
writeShape(obj,block)
|
||||
writeShape(sh,obj,block)
|
||||
return block
|
||||
|
||||
def writeShape(ob,dxfobject,nospline=False):
|
||||
def writeShape(sh,ob,dxfobject,nospline=False):
|
||||
"writes the object's shape contents in the given dxf object"
|
||||
processededges = []
|
||||
for wire in ob.Shape.Wires: # polylines
|
||||
for wire in sh.Wires: # polylines
|
||||
for e in wire.Edges:
|
||||
processededges.append(e.hashCode())
|
||||
if (len(wire.Edges) == 1) and (DraftGeomUtils.geomType(wire.Edges[0]) == "Circle"):
|
||||
|
@ -1319,22 +1350,32 @@ def writeShape(ob,dxfobject,nospline=False):
|
|||
dxfobject.append(dxfLibrary.PolyLine(getWire(wire,nospline), [0.0,0.0,0.0],
|
||||
int(DraftGeomUtils.isReallyClosed(wire)), color=getACI(ob),
|
||||
layer=getGroup(ob,exportList)))
|
||||
if len(processededges) < len(ob.Shape.Edges): # lone edges
|
||||
if len(processededges) < len(sh.Edges): # lone edges
|
||||
loneedges = []
|
||||
for e in ob.Shape.Edges:
|
||||
for e in sh.Edges:
|
||||
if not(e.hashCode() in processededges): loneedges.append(e)
|
||||
# print "lone edges ",loneedges
|
||||
for edge in loneedges:
|
||||
if (DraftGeomUtils.geomType(edge) == "BSplineCurve") and ((not nospline) or (len(edge.Vertexes) == 1)): # splines
|
||||
points = []
|
||||
spline = getSplineSegs(edge)
|
||||
for p in spline:
|
||||
points.append((p.x,p.y,p.z,None,None,0.0))
|
||||
dxfobject.append(dxfLibrary.PolyLine(points, [0.0,0.0,0.0],
|
||||
0, color=getACI(ob),
|
||||
layer=getGroup(ob,exportList)))
|
||||
if (len(edge.Vertexes) == 1) and (edge.Curve.isClosed()):
|
||||
# special case: 1-vert closed spline, approximate as a circle
|
||||
c = DraftGeomUtils.getCircleFromSpline(edge)
|
||||
if c:
|
||||
dxfobject.append(dxfLibrary.Circle(DraftVecUtils.tup(c.Curve.Center), c.Curve.Radius,
|
||||
color=getACI(ob),
|
||||
layer=getGroup(ob,exportList)))
|
||||
else:
|
||||
points = []
|
||||
spline = getSplineSegs(edge)
|
||||
for p in spline:
|
||||
points.append((p.x,p.y,p.z,None,None,0.0))
|
||||
dxfobject.append(dxfLibrary.PolyLine(points, [0.0,0.0,0.0],
|
||||
0, color=getACI(ob),
|
||||
layer=getGroup(ob,exportList)))
|
||||
elif DraftGeomUtils.geomType(edge) == "Circle": # curves
|
||||
center, radius, ang1, ang2 = getArcData(edge)
|
||||
if not isinstance(center,tuple):
|
||||
center = DraftVecUtils.tup(center)
|
||||
if len(edge.Vertexes) == 1: # circles
|
||||
dxfobject.append(dxfLibrary.Circle(center, radius,
|
||||
color=getACI(ob),
|
||||
|
@ -1389,27 +1430,37 @@ def export(objectslist,filename,nospline=False):
|
|||
for ob in exportList:
|
||||
print "processing ",ob.Name
|
||||
if ob.isDerivedFrom("Part::Feature"):
|
||||
if not ob.Shape.isNull():
|
||||
if FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Draft").GetBool("dxfmesh"):
|
||||
if FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Draft").GetBool("dxfmesh"):
|
||||
sh = None
|
||||
if not ob.Shape.isNull():
|
||||
writeMesh(ob,dxf)
|
||||
elif FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Draft").GetBool("dxfproject"):
|
||||
direction = FreeCADGui.ActiveDocument.ActiveView.getViewDirection()
|
||||
sh = projectShape(ob.Shape,direction)
|
||||
else:
|
||||
if ob.Shape.Volume > 0:
|
||||
sh = projectShape(ob.Shape,Vector(0,0,1))
|
||||
else:
|
||||
if ob.Shape.ShapeType == 'Compound':
|
||||
if (len(ob.Shape.Wires) == 1):
|
||||
sh = ob.Shape
|
||||
if sh:
|
||||
if not sh.isNull():
|
||||
if sh.ShapeType == 'Compound':
|
||||
if (len(sh.Wires) == 1):
|
||||
# only one wire in this compound, no lone edge -> polyline
|
||||
if (len(ob.Shape.Wires[0].Edges) == len(ob.Shape.Edges)):
|
||||
writeShape(ob,dxf,nospline)
|
||||
if (len(sh.Wires[0].Edges) == len(sh.Edges)):
|
||||
writeShape(sh,ob,dxf,nospline)
|
||||
else:
|
||||
# 1 wire + lone edges -> block
|
||||
block = getBlock(ob)
|
||||
block = getBlock(sh,ob)
|
||||
dxf.blocks.append(block)
|
||||
dxf.append(dxfLibrary.Insert(name=ob.Name.upper()))
|
||||
else:
|
||||
# all other cases: block
|
||||
block = getBlock(ob)
|
||||
block = getBlock(sh,ob)
|
||||
dxf.blocks.append(block)
|
||||
dxf.append(dxfLibrary.Insert(name=ob.Name.upper()))
|
||||
else:
|
||||
writeShape(ob,dxf,nospline)
|
||||
writeShape(sh,ob,dxf,nospline)
|
||||
|
||||
elif Draft.getType(ob) == "Annotation":
|
||||
# texts
|
||||
|
|
|
@ -2,9 +2,20 @@
|
|||
# (c) 2011 Werner Mayer LGPL
|
||||
|
||||
class DocumentObject(object):
|
||||
"""The Document object is the base class for all FreeCAD objects.
|
||||
Example of use:
|
||||
|
||||
import FreeCAD
|
||||
|
||||
doc=FreeCAD.newDocument()
|
||||
|
||||
myobj = doc.addObject("Mesh::FeaturePython","MyName")
|
||||
|
||||
myobj.addProperty("App::PropertyLinkList","Layers","Base", "Layers")"""
|
||||
def __init__(self):
|
||||
self.__object__=None
|
||||
def execute(self):
|
||||
"this method is executed on object creation and whenever the document is recomputed"
|
||||
raise Exception("Not yet implemented")
|
||||
#def onChanged(self,prop):
|
||||
# return None
|
||||
|
@ -14,67 +25,98 @@ class DocumentObject(object):
|
|||
# else:
|
||||
# return object.__getattribute__(self,attr)
|
||||
def addProperty(self,type,name='',group='',doc='',attr=0,readonly=False,hidden=False):
|
||||
"adds a new property to this object"
|
||||
self.__object__.addProperty(type,name,group,doc,attr,readonly,hidden)
|
||||
def supportedProperties(self):
|
||||
"lists the property types supported by this object"
|
||||
return self.__object__.supportedProperties()
|
||||
def isDerivedFrom(self, obj):
|
||||
"""returns True if this object is derived from the given C++ class, for
|
||||
example Part::Feature"""
|
||||
return self.__object__.isDerivedFrom(obj)
|
||||
def getAllDerivedFrom(self):
|
||||
"returns all parent C++ classes of this object"
|
||||
return self.__object__.getAllDerivedFrom()
|
||||
def getProperty(self,attr):
|
||||
"returns the value of a given property"
|
||||
return self.__object__.getPropertyByName(attr)
|
||||
def getTypeOfProperty(self,attr):
|
||||
"returns the type of a given property"
|
||||
return self.__object__.getTypeOfProperty(attr)
|
||||
def getGroupOfProperty(self,attr):
|
||||
"returns the group of a given property"
|
||||
return self.__object__.getGroupOfProperty(attr)
|
||||
def getDocumentationOfProperty(self,attr):
|
||||
"returns the documentation string of a given property"
|
||||
return self.__object__.getDocumentationOfProperty(attr)
|
||||
def touch(self):
|
||||
"marks this object to be recomputed"
|
||||
return self.__object__.touch()
|
||||
def purgeTouched(self):
|
||||
"removes the to-be-recomputed flag of this object"
|
||||
return self.__object__.purgeTouched()
|
||||
def __setstate__(self,value):
|
||||
"""allows to save custom attributes of this object as strings, so
|
||||
they can be saved when saving the FreeCAD document"""
|
||||
return None
|
||||
def __getstate__(self):
|
||||
"""reads values previously saved with __setstate__()"""
|
||||
return None
|
||||
@property
|
||||
def PropertiesList(self):
|
||||
"lists the current properties of this object"
|
||||
return self.__object__.PropertiesList
|
||||
@property
|
||||
def Type(self):
|
||||
"shows the C++ class of this object"
|
||||
return self.__object__.Type
|
||||
@property
|
||||
def Module(self):
|
||||
"gives the module this object is defined in"
|
||||
return self.__object__.Module
|
||||
@property
|
||||
def Content(self):
|
||||
"""shows the contents of the properties of this object as an xml string.
|
||||
This is the content that is saved when the file is saved by FreeCAD"""
|
||||
return self.__object__.Content
|
||||
@property
|
||||
def MemSize(self):
|
||||
"shows the amount of memory this object uses"
|
||||
return self.__object__.MemSize
|
||||
@property
|
||||
def Name(self):
|
||||
"the name ofthis object, unique in the FreeCAD document"
|
||||
return self.__object__.Name
|
||||
@property
|
||||
def Document(self):
|
||||
"the document this object is part of"
|
||||
return self.__object__.Document
|
||||
@property
|
||||
def State(self):
|
||||
"shows if this object is valid (presents no errors)"
|
||||
return self.__object__.State
|
||||
@property
|
||||
def ViewObject(self):
|
||||
return self.__object__.ViewObject
|
||||
@ViewObject.setter
|
||||
def ViewObject(self,value):
|
||||
"""returns or sets the ViewObject associated with this object. Returns
|
||||
None if FreeCAD is running in console mode"""
|
||||
self.__object__.ViewObject=value
|
||||
@property
|
||||
def InList(self):
|
||||
"lists the parents of this object"
|
||||
return self.__object__.InList
|
||||
@property
|
||||
def OutList(self):
|
||||
"lists the children of this object"
|
||||
return self.__object__.OutList
|
||||
|
||||
class ViewProvider(object):
|
||||
"""The ViewProvider is the counterpart of the DocumentObject in
|
||||
the GUI space. It is only present when FreeCAD runs in GUI mode.
|
||||
It contains all that is needed to represent the DocumentObject in
|
||||
the 3D view and the FreeCAD interface"""
|
||||
def __init__(self):
|
||||
self.__vobject__=None
|
||||
#def getIcon(self):
|
||||
|
@ -92,6 +134,7 @@ class ViewProvider(object):
|
|||
#def onChanged(self, prop):
|
||||
# return None
|
||||
def addDisplayMode(self,node,mode):
|
||||
"adds a coin node as a display mode to this object"
|
||||
self.__vobject__.addDisplayMode(node,mode)
|
||||
#def getDefaultDisplayMode(self):
|
||||
# return ""
|
||||
|
@ -100,65 +143,93 @@ class ViewProvider(object):
|
|||
#def setDisplayMode(self,mode):
|
||||
# return mode
|
||||
def addProperty(self,type,name='',group='',doc='',attr=0,readonly=False,hidden=False):
|
||||
"adds a new property to this object"
|
||||
self.__vobject__.addProperty(type,name,group,doc,attr,readonly,hidden)
|
||||
def update(self):
|
||||
"this method is executed whenever any of the properties of this ViewProvider changes"
|
||||
self.__vobject__.update()
|
||||
def show(self):
|
||||
"switches this object to visible"
|
||||
self.__vobject__.show()
|
||||
def hide(self):
|
||||
"switches this object to invisible"
|
||||
self.__vobject__.hide()
|
||||
def isVisible(self):
|
||||
"shows wether this object is visible or invisible"
|
||||
return self.__vobject__.isVisible()
|
||||
def toString(self):
|
||||
"returns a string representation of the coin node of this object"
|
||||
return self.__vobject__.toString()
|
||||
def startEditing(self,mode=0):
|
||||
"sets this object in edit mode"
|
||||
return self.__vobject__.startEditing(mode)
|
||||
def finishEditing(self):
|
||||
"leaves edit mode for this object"
|
||||
self.__vobject__.finishEditing()
|
||||
def isEditing(self):
|
||||
"shows wether this object is in edit mode"
|
||||
self.__vobject__.isEditing()
|
||||
def setTransformation(self,trsf):
|
||||
"defines a transformation for this object"
|
||||
return self.__vobject__.setTransformation(trsf)
|
||||
def supportedProperties(self):
|
||||
"lists the property types this ViewProvider supports"
|
||||
return self.__vobject__.supportedProperties()
|
||||
def isDerivedFrom(self, obj):
|
||||
"""returns True if this object is derived from the given C++ class, for
|
||||
example Part::Feature"""
|
||||
return self.__vobject__.isDerivedFrom(obj)
|
||||
def getAllDerivedFrom(self):
|
||||
"returns all parent C++ classes of this object"
|
||||
return self.__vobject__.getAllDerivedFrom()
|
||||
def getProperty(self,attr):
|
||||
"returns the value of a given property"
|
||||
return self.__vobject__.getPropertyByName(attr)
|
||||
def getTypeOfProperty(self,attr):
|
||||
"returns the type of a given property"
|
||||
return self.__vobject__.getTypeOfProperty(attr)
|
||||
def getGroupOfProperty(self,attr):
|
||||
"returns the group of a given property"
|
||||
return self.__vobject__.getGroupOfProperty(attr)
|
||||
def getDocumentationOfProperty(self,attr):
|
||||
"returns the documentation string of a given property"
|
||||
return self.__vobject__.getDocumentationOfProperty(attr)
|
||||
@property
|
||||
def Annotation(self):
|
||||
"returns the Annotation coin node of this object"
|
||||
return self.__vobject__.Annotation
|
||||
@property
|
||||
def RootNode(self):
|
||||
"returns the Root coin node of this object"
|
||||
return self.__vobject__.RootNode
|
||||
@property
|
||||
def DisplayModes(self):
|
||||
"lists the display modes of this object"
|
||||
return self.__vobject__.listDisplayModes()
|
||||
@property
|
||||
def PropertiesList(self):
|
||||
"lists the current properties of this object"
|
||||
return self.__vobject__.PropertiesList
|
||||
@property
|
||||
def Type(self):
|
||||
"shows the C++ class of this object"
|
||||
return self.__vobject__.Type
|
||||
@property
|
||||
def Module(self):
|
||||
"gives the module this object is defined in"
|
||||
return self.__vobject__.Module
|
||||
@property
|
||||
def Content(self):
|
||||
"""shows the contents of the properties of this object as an xml string.
|
||||
This is the content that is saved when the file is saved by FreeCAD"""
|
||||
return self.__vobject__.Content
|
||||
@property
|
||||
def MemSize(self):
|
||||
"shows the amount of memory this object uses"
|
||||
return self.__vobject__.MemSize
|
||||
@property
|
||||
def Object(self):
|
||||
"returns the DocumentObject this ViewProvider is associated to"
|
||||
return self.__vobject__.Object
|
||||
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
<File Id="DraftRcPy" Name="Draft_rc.py" DiskId="1" />
|
||||
<File Id="DraftVecUtilsPy" Name="DraftVecUtils.py" DiskId="1" />
|
||||
<File Id="DraftGeomUtilsPy" Name="DraftGeomUtils.py" DiskId="1" />
|
||||
<File Id="importDWGPy" Name="importDWG.py" DiskId="1" />
|
||||
</Component>
|
||||
<Directory Id="ModDraftLib" Name="draftlibs" FileSource="../../Mod/Draft/draftlibs">
|
||||
<Component Id="CompModDraftLib" Guid="d19c08b0-0747-11de-8c30-0800200c9a66" Win64='$(var.Win_64)' KeyPath="yes">
|
||||
|
|
Loading…
Reference in New Issue
Block a user