Switched resource compilation over to PySide and added an execute keybinding.
This commit is contained in:
parent
ec311d36d4
commit
c23e237bad
|
@ -136,7 +136,7 @@ class CadQueryExecuteScript:
|
|||
|
||||
def GetResources(self):
|
||||
return {"MenuText": "Execute Script",
|
||||
"Accel": "F2",
|
||||
"Accel": Settings.execute_keybinding,
|
||||
"ToolTip": "Executes the CadQuery script",
|
||||
"Pixmap": ":/icons/media-playback-start.svg"}
|
||||
|
||||
|
|
278
CadQuery_rc.py
278
CadQuery_rc.py
|
@ -2,282 +2,16 @@
|
|||
|
||||
# Resource object code
|
||||
#
|
||||
# Created by: The Resource Compiler for PyQt4 (Qt v4.8.7)
|
||||
# Created: Sat Mar 10 22:53:44 2018
|
||||
# by: The Resource Compiler for PySide (Qt v4.8.4)
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
from PyQt4 import QtCore
|
||||
|
||||
qt_resource_data = "\
|
||||
\x00\x00\x0f\x7d\
|
||||
\x3c\
|
||||
\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
|
||||
\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\
|
||||
\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\
|
||||
\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\
|
||||
\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\
|
||||
\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\
|
||||
\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\
|
||||
\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\
|
||||
\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\
|
||||
\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\
|
||||
\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\
|
||||
\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\
|
||||
\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\
|
||||
\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\
|
||||
\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\
|
||||
\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\
|
||||
\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\
|
||||
\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\
|
||||
\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\
|
||||
\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\
|
||||
\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\
|
||||
\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\
|
||||
\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\
|
||||
\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\
|
||||
\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\
|
||||
\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\
|
||||
\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\
|
||||
\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
|
||||
\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\
|
||||
\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\
|
||||
\x70\x65\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x32\x36\
|
||||
\x2e\x37\x33\x31\x31\x31\x35\x6d\x6d\x22\x0a\x20\x20\x20\x68\x65\
|
||||
\x69\x67\x68\x74\x3d\x22\x32\x34\x2e\x33\x37\x35\x35\x35\x39\x6d\
|
||||
\x6d\x22\x0a\x20\x20\x20\x76\x69\x65\x77\x42\x6f\x78\x3d\x22\x30\
|
||||
\x20\x30\x20\x39\x34\x2e\x37\x31\x36\x35\x35\x20\x38\x36\x2e\x33\
|
||||
\x37\x30\x30\x39\x22\x0a\x20\x20\x20\x69\x64\x3d\x22\x73\x76\x67\
|
||||
\x35\x34\x39\x35\x22\x0a\x20\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\
|
||||
\x3d\x22\x31\x2e\x31\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\
|
||||
\x70\x65\x3a\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x31\
|
||||
\x20\x72\x31\x33\x37\x32\x35\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\
|
||||
\x70\x6f\x64\x69\x3a\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x63\x61\
|
||||
\x64\x71\x75\x65\x72\x79\x5f\x6c\x6f\x67\x6f\x5f\x64\x61\x72\x6b\
|
||||
\x2e\x73\x76\x67\x22\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\
|
||||
\x20\x20\x20\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x35\x34\x39\x37\
|
||||
\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\x69\
|
||||
\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\x20\
|
||||
\x69\x64\x3d\x22\x62\x61\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x70\
|
||||
\x61\x67\x65\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\x66\
|
||||
\x66\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\
|
||||
\x6c\x6f\x72\x3d\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\x20\
|
||||
\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\
|
||||
\x3d\x22\x31\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\
|
||||
\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\x79\
|
||||
\x3d\x22\x30\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\
|
||||
\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\
|
||||
\x22\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\
|
||||
\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x34\x2e\x33\x37\x30\x39\x33\x36\
|
||||
\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\
|
||||
\x3a\x63\x78\x3d\x22\x34\x37\x2e\x33\x35\x38\x32\x37\x35\x22\x0a\
|
||||
\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\
|
||||
\x3d\x22\x34\x33\x2e\x31\x38\x35\x30\x34\x35\x22\x0a\x20\x20\x20\
|
||||
\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x64\x6f\x63\x75\x6d\
|
||||
\x65\x6e\x74\x2d\x75\x6e\x69\x74\x73\x3d\x22\x70\x78\x22\x0a\x20\
|
||||
\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\
|
||||
\x72\x65\x6e\x74\x2d\x6c\x61\x79\x65\x72\x3d\x22\x6c\x61\x79\x65\
|
||||
\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\
|
||||
\x64\x3d\x22\x66\x61\x6c\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x66\
|
||||
\x69\x74\x2d\x6d\x61\x72\x67\x69\x6e\x2d\x74\x6f\x70\x3d\x22\x30\
|
||||
\x22\x0a\x20\x20\x20\x20\x20\x66\x69\x74\x2d\x6d\x61\x72\x67\x69\
|
||||
\x6e\x2d\x6c\x65\x66\x74\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\
|
||||
\x66\x69\x74\x2d\x6d\x61\x72\x67\x69\x6e\x2d\x72\x69\x67\x68\x74\
|
||||
\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x66\x69\x74\x2d\x6d\x61\
|
||||
\x72\x67\x69\x6e\x2d\x62\x6f\x74\x74\x6f\x6d\x3d\x22\x30\x22\x0a\
|
||||
\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\
|
||||
\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x38\x35\x35\
|
||||
\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\
|
||||
\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\x31\
|
||||
\x30\x35\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\
|
||||
\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x36\x35\x22\
|
||||
\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\
|
||||
\x69\x6e\x64\x6f\x77\x2d\x79\x3d\x22\x32\x34\x22\x0a\x20\x20\x20\
|
||||
\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\
|
||||
\x77\x2d\x6d\x61\x78\x69\x6d\x69\x7a\x65\x64\x3d\x22\x31\x22\x20\
|
||||
\x2f\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\x20\
|
||||
\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\x61\
|
||||
\x35\x35\x30\x30\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\x3a\
|
||||
\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\x3a\x57\
|
||||
\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\
|
||||
\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\x20\x20\
|
||||
\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\x6d\
|
||||
\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\
|
||||
\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\
|
||||
\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\x20\x20\
|
||||
\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\x65\
|
||||
\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\
|
||||
\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\x74\
|
||||
\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\x20\x20\
|
||||
\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\x20\x2f\
|
||||
\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\x6f\x72\
|
||||
\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\x44\x46\
|
||||
\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\x3e\x0a\
|
||||
\x20\x20\x3c\x67\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\
|
||||
\x70\x65\x3a\x6c\x61\x62\x65\x6c\x3d\x22\x4c\x61\x79\x65\x72\x20\
|
||||
\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\
|
||||
\x3a\x67\x72\x6f\x75\x70\x6d\x6f\x64\x65\x3d\x22\x6c\x61\x79\x65\
|
||||
\x72\x22\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6c\x61\x79\x65\
|
||||
\x72\x31\x22\x0a\x20\x20\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\
|
||||
\x72\x6d\x3d\x22\x74\x72\x61\x6e\x73\x6c\x61\x74\x65\x28\x2d\x32\
|
||||
\x38\x34\x2e\x30\x37\x30\x33\x2c\x2d\x34\x37\x37\x2e\x37\x34\x38\
|
||||
\x35\x39\x29\x22\x3e\x0a\x20\x20\x20\x20\x3c\x70\x61\x74\x68\x0a\
|
||||
\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\
|
||||
\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\
|
||||
\x75\x72\x65\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\
|
||||
\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x32\x39\x38\x30\
|
||||
\x62\x39\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\
|
||||
\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\
|
||||
\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x32\x39\x38\x30\
|
||||
\x62\x39\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\
|
||||
\x33\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\
|
||||
\x3a\x62\x75\x74\x74\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\
|
||||
\x65\x6a\x6f\x69\x6e\x3a\x72\x6f\x75\x6e\x64\x3b\x73\x74\x72\x6f\
|
||||
\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\
|
||||
\x20\x20\x20\x20\x20\x64\x3d\x22\x6d\x20\x32\x38\x35\x2e\x35\x37\
|
||||
\x30\x33\x2c\x34\x37\x39\x2e\x32\x34\x38\x35\x39\x20\x39\x31\x2e\
|
||||
\x37\x31\x36\x35\x35\x2c\x30\x20\x30\x2c\x38\x33\x2e\x33\x37\x30\
|
||||
\x30\x39\x20\x2d\x39\x31\x2e\x37\x31\x36\x35\x35\x2c\x30\x20\x7a\
|
||||
\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\
|
||||
\x68\x34\x32\x36\x36\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x67\
|
||||
\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\
|
||||
\x6f\x6e\x74\x2d\x73\x74\x79\x6c\x65\x3a\x6e\x6f\x72\x6d\x61\x6c\
|
||||
\x3b\x66\x6f\x6e\x74\x2d\x77\x65\x69\x67\x68\x74\x3a\x6e\x6f\x72\
|
||||
\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x73\x69\x7a\x65\x3a\x34\x30\
|
||||
\x70\x78\x3b\x6c\x69\x6e\x65\x2d\x68\x65\x69\x67\x68\x74\x3a\x31\
|
||||
\x32\x35\x25\x3b\x66\x6f\x6e\x74\x2d\x66\x61\x6d\x69\x6c\x79\x3a\
|
||||
\x73\x61\x6e\x73\x2d\x73\x65\x72\x69\x66\x3b\x6c\x65\x74\x74\x65\
|
||||
\x72\x2d\x73\x70\x61\x63\x69\x6e\x67\x3a\x30\x70\x78\x3b\x77\x6f\
|
||||
\x72\x64\x2d\x73\x70\x61\x63\x69\x6e\x67\x3a\x30\x70\x78\x3b\x66\
|
||||
\x69\x6c\x6c\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x66\x69\x6c\x6c\
|
||||
\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x73\x74\x72\x6f\x6b\
|
||||
\x65\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\
|
||||
\x64\x74\x68\x3a\x31\x70\x78\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\
|
||||
\x69\x6e\x65\x63\x61\x70\x3a\x62\x75\x74\x74\x3b\x73\x74\x72\x6f\
|
||||
\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\
|
||||
\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\
|
||||
\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x74\
|
||||
\x65\x78\x74\x34\x38\x37\x33\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\
|
||||
\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x64\
|
||||
\x3d\x22\x6d\x20\x33\x31\x33\x2e\x34\x33\x32\x39\x38\x2c\x35\x32\
|
||||
\x39\x2e\x33\x37\x37\x30\x31\x20\x71\x20\x32\x2e\x37\x33\x34\x33\
|
||||
\x38\x2c\x30\x20\x34\x2e\x34\x34\x33\x33\x36\x2c\x2d\x31\x2e\x35\
|
||||
\x30\x33\x39\x20\x31\x2e\x37\x30\x38\x39\x39\x2c\x2d\x31\x2e\x35\
|
||||
\x30\x33\x39\x31\x20\x31\x2e\x37\x37\x37\x33\x35\x2c\x2d\x33\x2e\
|
||||
\x39\x39\x39\x30\x33\x20\x6c\x20\x39\x2e\x32\x36\x32\x36\x39\x2c\
|
||||
\x30\x20\x71\x20\x2d\x30\x2e\x30\x33\x34\x32\x2c\x33\x2e\x37\x35\
|
||||
\x39\x37\x37\x20\x2d\x32\x2e\x30\x35\x30\x37\x38\x2c\x36\x2e\x39\
|
||||
\x30\x34\x33\x20\x2d\x32\x2e\x30\x31\x36\x36\x2c\x33\x2e\x31\x31\
|
||||
\x30\x33\x35\x20\x2d\x35\x2e\x35\x33\x37\x31\x31\x2c\x34\x2e\x38\
|
||||
\x35\x33\x35\x32\x20\x2d\x33\x2e\x34\x38\x36\x33\x33\x2c\x31\x2e\
|
||||
\x37\x30\x38\x39\x38\x20\x2d\x37\x2e\x37\x32\x34\x36\x31\x2c\x31\
|
||||
\x2e\x37\x30\x38\x39\x38\x20\x2d\x37\x2e\x39\x32\x39\x36\x39\x2c\
|
||||
\x30\x20\x2d\x31\x32\x2e\x35\x30\x39\x37\x36\x2c\x2d\x35\x2e\x30\
|
||||
\x32\x34\x34\x31\x20\x2d\x34\x2e\x35\x38\x30\x30\x38\x2c\x2d\x35\
|
||||
\x2e\x30\x35\x38\x36\x20\x2d\x34\x2e\x35\x38\x30\x30\x38\x2c\x2d\
|
||||
\x31\x33\x2e\x39\x34\x35\x33\x32\x20\x6c\x20\x30\x2c\x2d\x30\x2e\
|
||||
\x36\x34\x39\x34\x31\x20\x71\x20\x30\x2c\x2d\x38\x2e\x35\x34\x34\
|
||||
\x39\x32\x20\x34\x2e\x35\x34\x35\x39\x2c\x2d\x31\x33\x2e\x36\x33\
|
||||
\x37\x36\x39\x20\x34\x2e\x35\x34\x35\x38\x39\x2c\x2d\x35\x2e\x30\
|
||||
\x39\x32\x37\x38\x20\x31\x32\x2e\x34\x37\x35\x35\x38\x2c\x2d\x35\
|
||||
\x2e\x30\x39\x32\x37\x38\x20\x36\x2e\x39\x33\x38\x34\x38\x2c\x30\
|
||||
\x20\x31\x31\x2e\x31\x30\x38\x34\x2c\x33\x2e\x39\x36\x34\x38\x35\
|
||||
\x20\x34\x2e\x32\x30\x34\x31\x2c\x33\x2e\x39\x33\x30\x36\x36\x20\
|
||||
\x34\x2e\x32\x37\x32\x34\x36\x2c\x31\x30\x2e\x34\x39\x33\x31\x36\
|
||||
\x20\x6c\x20\x2d\x39\x2e\x32\x36\x32\x36\x39\x2c\x30\x20\x71\x20\
|
||||
\x2d\x30\x2e\x30\x36\x38\x34\x2c\x2d\x32\x2e\x38\x37\x31\x30\x39\
|
||||
\x20\x2d\x31\x2e\x37\x37\x37\x33\x35\x2c\x2d\x34\x2e\x36\x34\x38\
|
||||
\x34\x34\x20\x2d\x31\x2e\x37\x30\x38\x39\x38\x2c\x2d\x31\x2e\x38\
|
||||
\x31\x31\x35\x32\x20\x2d\x34\x2e\x35\x31\x31\x37\x32\x2c\x2d\x31\
|
||||
\x2e\x38\x31\x31\x35\x32\x20\x2d\x33\x2e\x34\x35\x32\x31\x34\x2c\
|
||||
\x30\x20\x2d\x35\x2e\x32\x32\x39\x34\x39\x2c\x32\x2e\x35\x32\x39\
|
||||
\x33\x20\x2d\x31\x2e\x37\x34\x33\x31\x36\x2c\x32\x2e\x34\x39\x35\
|
||||
\x31\x31\x20\x2d\x31\x2e\x37\x34\x33\x31\x36\x2c\x38\x2e\x31\x33\
|
||||
\x34\x37\x36\x20\x6c\x20\x30\x2c\x31\x2e\x30\x32\x35\x33\x39\x20\
|
||||
\x71\x20\x30\x2c\x35\x2e\x37\x30\x38\x30\x31\x20\x31\x2e\x37\x34\
|
||||
\x33\x31\x36\x2c\x38\x2e\x32\x30\x33\x31\x33\x20\x31\x2e\x37\x34\
|
||||
\x33\x31\x37\x2c\x32\x2e\x34\x39\x35\x31\x31\x20\x35\x2e\x32\x39\
|
||||
\x37\x38\x35\x2c\x32\x2e\x34\x39\x35\x31\x31\x20\x7a\x22\x0a\x20\
|
||||
\x20\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\
|
||||
\x6f\x6e\x74\x2d\x73\x74\x79\x6c\x65\x3a\x6e\x6f\x72\x6d\x61\x6c\
|
||||
\x3b\x66\x6f\x6e\x74\x2d\x76\x61\x72\x69\x61\x6e\x74\x3a\x6e\x6f\
|
||||
\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x77\x65\x69\x67\x68\x74\
|
||||
\x3a\x62\x6f\x6c\x64\x3b\x66\x6f\x6e\x74\x2d\x73\x74\x72\x65\x74\
|
||||
\x63\x68\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x73\
|
||||
\x69\x7a\x65\x3a\x37\x30\x70\x78\x3b\x66\x6f\x6e\x74\x2d\x66\x61\
|
||||
\x6d\x69\x6c\x79\x3a\x52\x6f\x62\x6f\x74\x6f\x3b\x2d\x69\x6e\x6b\
|
||||
\x73\x63\x61\x70\x65\x2d\x66\x6f\x6e\x74\x2d\x73\x70\x65\x63\x69\
|
||||
\x66\x69\x63\x61\x74\x69\x6f\x6e\x3a\x27\x52\x6f\x62\x6f\x74\x6f\
|
||||
\x20\x42\x6f\x6c\x64\x27\x3b\x66\x69\x6c\x6c\x3a\x23\x66\x66\x66\
|
||||
\x66\x66\x66\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\
|
||||
\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\
|
||||
\x22\x70\x61\x74\x68\x34\x32\x34\x31\x22\x20\x2f\x3e\x0a\x20\x20\
|
||||
\x20\x20\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x20\
|
||||
\x20\x20\x20\x64\x3d\x22\x6d\x20\x33\x33\x33\x2e\x30\x31\x37\x39\
|
||||
\x34\x2c\x35\x31\x37\x2e\x38\x32\x34\x32\x38\x20\x71\x20\x30\x2c\
|
||||
\x2d\x38\x2e\x37\x31\x35\x38\x32\x20\x33\x2e\x38\x36\x32\x33\x31\
|
||||
\x2c\x2d\x31\x33\x2e\x37\x37\x34\x34\x31\x20\x33\x2e\x38\x39\x36\
|
||||
\x34\x38\x2c\x2d\x35\x2e\x30\x35\x38\x36\x20\x31\x30\x2e\x36\x36\
|
||||
\x34\x30\x36\x2c\x2d\x35\x2e\x30\x35\x38\x36\x20\x35\x2e\x39\x34\
|
||||
\x37\x32\x37\x2c\x30\x20\x39\x2e\x34\x36\x37\x37\x37\x2c\x34\x2e\
|
||||
\x35\x34\x35\x39\x20\x6c\x20\x30\x2e\x36\x34\x39\x34\x32\x2c\x2d\
|
||||
\x33\x2e\x38\x36\x32\x33\x20\x38\x2e\x36\x38\x31\x36\x34\x2c\x30\
|
||||
\x20\x30\x2c\x35\x31\x2e\x32\x30\x31\x31\x37\x20\x2d\x39\x2e\x39\
|
||||
\x31\x32\x31\x31\x2c\x30\x20\x30\x2c\x2d\x31\x37\x2e\x33\x39\x37\
|
||||
\x34\x36\x20\x71\x20\x2d\x33\x2e\x34\x31\x37\x39\x37\x2c\x33\x2e\
|
||||
\x38\x36\x32\x33\x20\x2d\x38\x2e\x39\x35\x35\x30\x38\x2c\x33\x2e\
|
||||
\x38\x36\x32\x33\x20\x2d\x36\x2e\x35\x39\x36\x36\x38\x2c\x30\x20\
|
||||
\x2d\x31\x30\x2e\x35\x32\x37\x33\x34\x2c\x2d\x35\x2e\x31\x32\x36\
|
||||
\x39\x35\x20\x2d\x33\x2e\x39\x33\x30\x36\x37\x2c\x2d\x35\x2e\x31\
|
||||
\x32\x36\x39\x35\x20\x2d\x33\x2e\x39\x33\x30\x36\x37\x2c\x2d\x31\
|
||||
\x34\x2e\x33\x38\x39\x36\x35\x20\x7a\x20\x6d\x20\x39\x2e\x38\x37\
|
||||
\x37\x39\x33\x2c\x30\x2e\x37\x31\x37\x37\x37\x20\x71\x20\x30\x2c\
|
||||
\x35\x2e\x32\x39\x37\x38\x35\x20\x31\x2e\x38\x34\x35\x37\x31\x2c\
|
||||
\x38\x2e\x30\x36\x36\x34\x31\x20\x31\x2e\x38\x37\x39\x38\x38\x2c\
|
||||
\x32\x2e\x37\x36\x38\x35\x35\x20\x35\x2e\x32\x36\x33\x36\x37\x2c\
|
||||
\x32\x2e\x37\x36\x38\x35\x35\x20\x34\x2e\x35\x34\x35\x39\x2c\x30\
|
||||
\x20\x36\x2e\x34\x32\x35\x37\x38\x2c\x2d\x33\x2e\x36\x32\x33\x30\
|
||||
\x34\x20\x6c\x20\x30\x2c\x2d\x31\x35\x2e\x32\x37\x38\x33\x32\x20\
|
||||
\x71\x20\x2d\x31\x2e\x38\x34\x35\x37\x2c\x2d\x33\x2e\x34\x38\x36\
|
||||
\x33\x33\x20\x2d\x36\x2e\x33\x35\x37\x34\x32\x2c\x2d\x33\x2e\x34\
|
||||
\x38\x36\x33\x33\x20\x2d\x33\x2e\x34\x31\x37\x39\x37\x2c\x30\x20\
|
||||
\x2d\x35\x2e\x32\x39\x37\x38\x35\x2c\x32\x2e\x37\x36\x38\x35\x35\
|
||||
\x20\x2d\x31\x2e\x38\x37\x39\x38\x39\x2c\x32\x2e\x37\x36\x38\x35\
|
||||
\x36\x20\x2d\x31\x2e\x38\x37\x39\x38\x39\x2c\x38\x2e\x37\x38\x34\
|
||||
\x31\x38\x20\x7a\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x73\
|
||||
\x74\x79\x6c\x65\x3d\x22\x66\x6f\x6e\x74\x2d\x73\x74\x79\x6c\x65\
|
||||
\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x76\x61\x72\
|
||||
\x69\x61\x6e\x74\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\
|
||||
\x2d\x77\x65\x69\x67\x68\x74\x3a\x62\x6f\x6c\x64\x3b\x66\x6f\x6e\
|
||||
\x74\x2d\x73\x74\x72\x65\x74\x63\x68\x3a\x6e\x6f\x72\x6d\x61\x6c\
|
||||
\x3b\x66\x6f\x6e\x74\x2d\x73\x69\x7a\x65\x3a\x37\x30\x70\x78\x3b\
|
||||
\x66\x6f\x6e\x74\x2d\x66\x61\x6d\x69\x6c\x79\x3a\x52\x6f\x62\x6f\
|
||||
\x74\x6f\x3b\x2d\x69\x6e\x6b\x73\x63\x61\x70\x65\x2d\x66\x6f\x6e\
|
||||
\x74\x2d\x73\x70\x65\x63\x69\x66\x69\x63\x61\x74\x69\x6f\x6e\x3a\
|
||||
\x27\x52\x6f\x62\x6f\x74\x6f\x20\x42\x6f\x6c\x64\x27\x3b\x66\x69\
|
||||
\x6c\x6c\x3a\x23\x66\x66\x66\x66\x66\x66\x3b\x66\x69\x6c\x6c\x2d\
|
||||
\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x22\x0a\x20\x20\x20\x20\x20\
|
||||
\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x34\x32\x34\x33\
|
||||
\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x67\x3e\x0a\x20\x20\
|
||||
\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\
|
||||
"
|
||||
|
||||
qt_resource_name = "\
|
||||
\x00\x05\
|
||||
\x00\x6f\xa6\x53\
|
||||
\x00\x69\
|
||||
\x00\x63\x00\x6f\x00\x6e\x00\x73\
|
||||
\x00\x0b\
|
||||
\x05\x72\xb2\xa7\
|
||||
\x00\x43\
|
||||
\x00\x51\x00\x5f\x00\x4c\x00\x6f\x00\x67\x00\x6f\x00\x2e\x00\x73\x00\x76\x00\x67\
|
||||
"
|
||||
|
||||
qt_resource_struct = "\
|
||||
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\
|
||||
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x02\
|
||||
\x00\x00\x00\x10\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\
|
||||
"
|
||||
from PySide import QtCore
|
||||
|
||||
qt_resource_data = "\x00\x00\x0f}<?xml version=\x221.0\x22 encoding=\x22UTF-8\x22 standalone=\x22no\x22?>\x0a<!-- Created with Inkscape (http://www.inkscape.org/) -->\x0a\x0a<svg\x0a xmlns:dc=\x22http://purl.org/dc/elements/1.1/\x22\x0a xmlns:cc=\x22http://creativecommons.org/ns#\x22\x0a xmlns:rdf=\x22http://www.w3.org/1999/02/22-rdf-syntax-ns#\x22\x0a xmlns:svg=\x22http://www.w3.org/2000/svg\x22\x0a xmlns=\x22http://www.w3.org/2000/svg\x22\x0a xmlns:sodipodi=\x22http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd\x22\x0a xmlns:inkscape=\x22http://www.inkscape.org/namespaces/inkscape\x22\x0a width=\x2226.731115mm\x22\x0a height=\x2224.375559mm\x22\x0a viewBox=\x220 0 94.71655 86.37009\x22\x0a id=\x22svg5495\x22\x0a version=\x221.1\x22\x0a inkscape:version=\x220.91 r13725\x22\x0a sodipodi:docname=\x22cadquery_logo_dark.svg\x22>\x0a <defs\x0a id=\x22defs5497\x22 />\x0a <sodipodi:namedview\x0a id=\x22base\x22\x0a pagecolor=\x22#ffffff\x22\x0a bordercolor=\x22#666666\x22\x0a borderopacity=\x221.0\x22\x0a inkscape:pageopacity=\x220.0\x22\x0a inkscape:pageshadow=\x222\x22\x0a inkscape:zoom=\x224.3709362\x22\x0a inkscape:cx=\x2247.358275\x22\x0a inkscape:cy=\x2243.185045\x22\x0a inkscape:document-units=\x22px\x22\x0a inkscape:current-layer=\x22layer1\x22\x0a showgrid=\x22false\x22\x0a fit-margin-top=\x220\x22\x0a fit-margin-left=\x220\x22\x0a fit-margin-right=\x220\x22\x0a fit-margin-bottom=\x220\x22\x0a inkscape:window-width=\x221855\x22\x0a inkscape:window-height=\x221056\x22\x0a inkscape:window-x=\x2265\x22\x0a inkscape:window-y=\x2224\x22\x0a inkscape:window-maximized=\x221\x22 />\x0a <metadata\x0a id=\x22metadata5500\x22>\x0a <rdf:RDF>\x0a <cc:Work\x0a rdf:about=\x22\x22>\x0a <dc:format>image/svg+xml</dc:format>\x0a <dc:type\x0a rdf:resource=\x22http://purl.org/dc/dcmitype/StillImage\x22 />\x0a <dc:title />\x0a </cc:Work>\x0a </rdf:RDF>\x0a </metadata>\x0a <g\x0a inkscape:label=\x22Layer 1\x22\x0a inkscape:groupmode=\x22layer\x22\x0a id=\x22layer1\x22\x0a transform=\x22translate(-284.0703,-477.74859)\x22>\x0a <path\x0a inkscape:connector-curvature=\x220\x22\x0a style=\x22fill:#2980b9;fill-opacity:1;fill-rule:evenodd;stroke:#2980b9;stroke-width:3;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1\x22\x0a d=\x22m 285.5703,479.24859 91.71655,0 0,83.37009 -91.71655,0 z\x22\x0a id=\x22path4266\x22 />\x0a <g\x0a style=\x22font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1\x22\x0a id=\x22text4873\x22>\x0a <path\x0a d=\x22m 313.43298,529.37701 q 2.73438,0 4.44336,-1.5039 1.70899,-1.50391 1.77735,-3.99903 l 9.26269,0 q -0.0342,3.75977 -2.05078,6.9043 -2.0166,3.11035 -5.53711,4.85352 -3.48633,1.70898 -7.72461,1.70898 -7.92969,0 -12.50976,-5.02441 -4.58008,-5.0586 -4.58008,-13.94532 l 0,-0.64941 q 0,-8.54492 4.5459,-13.63769 4.54589,-5.09278 12.47558,-5.09278 6.93848,0 11.1084,3.96485 4.2041,3.93066 4.27246,10.49316 l -9.26269,0 q -0.0684,-2.87109 -1.77735,-4.64844 -1.70898,-1.81152 -4.51172,-1.81152 -3.45214,0 -5.22949,2.5293 -1.74316,2.49511 -1.74316,8.13476 l 0,1.02539 q 0,5.70801 1.74316,8.20313 1.74317,2.49511 5.29785,2.49511 z\x22\x0a style=\x22font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:70px;font-family:Roboto;-inkscape-font-specification:'Roboto Bold';fill:#ffffff;fill-opacity:1\x22\x0a id=\x22path4241\x22 />\x0a <path\x0a d=\x22m 333.01794,517.82428 q 0,-8.71582 3.86231,-13.77441 3.89648,-5.0586 10.66406,-5.0586 5.94727,0 9.46777,4.5459 l 0.64942,-3.8623 8.68164,0 0,51.20117 -9.91211,0 0,-17.39746 q -3.41797,3.8623 -8.95508,3.8623 -6.59668,0 -10.52734,-5.12695 -3.93067,-5.12695 -3.93067,-14.38965 z m 9.87793,0.71777 q 0,5.29785 1.84571,8.06641 1.87988,2.76855 5.26367,2.76855 4.5459,0 6.42578,-3.62304 l 0,-15.27832 q -1.8457,-3.48633 -6.35742,-3.48633 -3.41797,0 -5.29785,2.76855 -1.87989,2.76856 -1.87989,8.78418 z\x22\x0a style=\x22font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:70px;font-family:Roboto;-inkscape-font-specification:'Roboto Bold';fill:#ffffff;fill-opacity:1\x22\x0a id=\x22path4243\x22 />\x0a </g>\x0a </g>\x0a</svg>\x0a"
|
||||
qt_resource_name = "\x00\x05\x00o\xa6S\x00i\x00c\x00o\x00n\x00s\x00\x0b\x05r\xb2\xa7\x00C\x00Q\x00_\x00L\x00o\x00g\x00o\x00.\x00s\x00v\x00g"
|
||||
qt_resource_struct = "\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x10\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00"
|
||||
def qInitResources():
|
||||
QtCore.qRegisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data)
|
||||
|
||||
|
|
|
@ -1,21 +1,42 @@
|
|||
language: python
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- python: 2.7
|
||||
- python: 3.6
|
||||
env: FREECAD_LIB="$HOME/miniconda/envs/freecad_cq3/lib/"
|
||||
|
||||
before_install:
|
||||
- sudo add-apt-repository -y ppa:freecad-maintainers/freecad-stable
|
||||
- sudo apt-get update -qq
|
||||
- if [[ "$TRAVIS_PYTHON_VERSION" == "3.6" ]]; then
|
||||
wget https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh -O miniconda.sh;
|
||||
bash miniconda.sh -b -p $HOME/miniconda;
|
||||
export PATH="$HOME/miniconda/bin:$PATH";
|
||||
hash -r;
|
||||
conda config --set always_yes yes --set changeps1 no;
|
||||
conda update -q conda;
|
||||
conda info -a;
|
||||
conda create -y -q -n freecad_cq3 -c freecad -c conda-forge freecad=0.17=py36_11 occt=7.2.0=occt7.2.0_0 python=3.6 pyparsing conda mock;
|
||||
source ~/miniconda/bin/activate freecad_cq3;
|
||||
else
|
||||
sudo add-apt-repository -y ppa:freecad-maintainers/freecad-stable;
|
||||
sudo apt-get update -qq;
|
||||
sudo apt-get install -y freecad freecad-doc;
|
||||
pip install -r requirements-dev.txt;
|
||||
pip install travis-sphinx;
|
||||
pip install sphinx_rtd_theme;
|
||||
fi
|
||||
|
||||
install:
|
||||
- sudo apt-get install -y freecad freecad-doc
|
||||
- gcc --version
|
||||
- g++ --version
|
||||
- python ./setup.py install
|
||||
- pip install -r requirements-dev.txt
|
||||
- pip install travis-sphinx
|
||||
- pip install sphinx_rtd_theme
|
||||
- python setup.py install;
|
||||
|
||||
script:
|
||||
- coverage run --source=cadquery ./runtests.py
|
||||
- travis-sphinx build --nowarn --source=doc
|
||||
- if [[ "$TRAVIS_PYTHON_VERSION" == "2.7" ]]; then
|
||||
coverage run --source=cadquery --omit=cadquery/cq_directive.py ./runtests.py;
|
||||
travis-sphinx build --nowarn --source=doc;
|
||||
fi
|
||||
- python runtests.py
|
||||
|
||||
after_success:
|
||||
after_script:
|
||||
- coveralls
|
||||
- travis-sphinx deploy
|
||||
|
||||
|
@ -23,11 +44,10 @@ branches:
|
|||
except:
|
||||
- pythonocc
|
||||
- 2_0_branch
|
||||
|
||||
deploy:
|
||||
deploy:
|
||||
provider: pypi
|
||||
user: dcowden
|
||||
password:
|
||||
secure: aP02wBbry1j3hYG/w++siF1lk26teuRQlPAx1c+ec8fxUw+bECa2HbPQHcIvSXB5N6nc6P3L9LjHt9ktm+Dn6FLJu3qWYNGAZx9PTn24ug0iAmB+JyNrsET3nK6WUKR1XpBqvjKgdpukd1Hknh2FSzYoyUvFWH9/CovITCFN3jo=
|
||||
on:
|
||||
tags: true
|
||||
tags: true
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
<p align="center">
|
||||
<img src="http://dcowden.github.io/cadquery/_static/cadquery_logo_dark.svg" width="100"/>
|
||||
</p>
|
||||
|
||||
What is a CadQuery?
|
||||
========================================
|
||||
|
||||
[](https://travis-ci.org/dcowden/cadquery?branch=master)
|
||||
[](https://coveralls.io/r/dcowden/cadquery)
|
||||
[](https://coveralls.io/github/dcowden/cadquery?branch=master)
|
||||
[](https://github.com/dcowden/cadquery/releases/tag/v0.3.0)
|
||||
[](https://github.com/dcowden/cadquery/blob/master/LICENSE)
|
||||
|
||||
|
@ -17,9 +21,46 @@ CadQuery has several goals:
|
|||
|
||||
Using CadQuery, you can write short, simple scripts that produce high quality CAD models. It is easy to make many different objects using a single script that can be customized.
|
||||
|
||||
Full Documentation and a Welcoming Community
|
||||
============================
|
||||
You can find the full cadquery documentation at http://dcowden.github.io/cadquery
|
||||
|
||||
We also have a Google Group to make it easy to get help from other CadQuery users. We want you to feel welcome and encourage you to join the group and introduce yourself. We would also love to hear what you are doing with CadQuery. https://groups.google.com/forum/#!forum/cadquery
|
||||
|
||||
Getting Started With CadQuery
|
||||
========================================
|
||||
|
||||
Installation instructions for all following use cases can be found [here](http://dcowden.github.io/cadquery/installation.html).
|
||||
|
||||
It is currently possible to use CadQuery for your own projects in 4 different ways:
|
||||
* as a plugin for FreeCAD
|
||||
* using the Docker Image to operate CadQuery as a CLI
|
||||
* as a plugin running on a Jupyter Notebook server
|
||||
* a standalone installation
|
||||
|
||||
## I just want to try things out!
|
||||
|
||||
If you are interested in trying CadQuery without installing anything, your best option is to experiment with CadQuery scripts running on a Jupyter server.
|
||||
|
||||
[](https://mybinder.org/v2/gh/RustyVermeer/tryCQ/master)
|
||||
|
||||
That button will launch a Jupyter Server pre-configured with CadQuery and its dependencies. It contains a folder with many useful examples to showcase CadQuery's features.
|
||||
|
||||
## I'd like to use CadQuery on my own setup
|
||||
|
||||
The easiest way to get started with CadQuery is to Install FreeCAD (version 16+) (http://www.freecadweb.org/), and then to use our great CadQuery-FreeCAD plugin here: https://github.com/jmwright/cadquery-freecad-module
|
||||
|
||||
It includes the latest version of cadquery already bundled, and has super-easy installation on Mac, Windows, and Unix.
|
||||
|
||||
It has tons of awesome features like integration with FreeCAD so you can see your objects, code-autocompletion, an examples bundle, and script saving/loading. Its definitely the best way to kick the tires!
|
||||
|
||||
## I have other ideas and want to run things my own way
|
||||
|
||||
Awesome! CadQuery is built with this attitude in mind. If none of the existing usage methods work for you, you are more than welcome to forge your own path. You'll probably find the most success using the Docker image. You can alternatively install CadQuery as a standalone package.
|
||||
|
||||
Getting Started with the docker image
|
||||
=======================================
|
||||
The caduery docker image (https://hub.docker.com/r/dcowden/cadquery/) includes cadquery and all of its dependencies. It can be used to run cadquery scripts without any installation required ( other than docker, of course)
|
||||
The CadQuery docker image (https://hub.docker.com/r/dcowden/cadquery/) includes cadquery and all of its dependencies. It can be used to run cadquery scripts without any installation required ( other than docker, of course)
|
||||
|
||||
Examples:
|
||||
|
||||
|
@ -33,7 +74,7 @@ Build a local model using stdin/stdout::
|
|||
|
||||
... STEP output on the console
|
||||
|
||||
Build local models and output to the same directory::
|
||||
Build local models and output to the same directory:
|
||||
|
||||
docker run -v $PWD:/home/cq -i dcowden/cadquery:latest build --in_spec Ex001_Simple_Block.py --format STEP
|
||||
INFO: Reading from file 'Ex001_Simple_Block.py'
|
||||
|
@ -46,26 +87,8 @@ Build local models and output to the same directory::
|
|||
INFO: Script Generated 1 result Objects
|
||||
INFO: Writing STEP Output to './cqobject-1.STEP'
|
||||
|
||||
|
||||
|
||||
Full Documentation
|
||||
============================
|
||||
You can find the full cadquery documentation at http://dcowden.github.io/cadquery
|
||||
|
||||
Getting Started With CadQuery
|
||||
========================================
|
||||
|
||||
The easiest way to get started with CadQuery is to Install FreeCAD (version 16+) (http://www.freecadweb.org/), and then to use our great CadQuery-FreeCAD plugin here: https://github.com/jmwright/cadquery-freecad-module
|
||||
|
||||
|
||||
It includes the latest version of cadquery alreadby bundled, and has super-easy installation on Mac, Windows, and Unix.
|
||||
|
||||
It has tons of awesome features like integration with FreeCAD so you can see your objects, code-autocompletion, an examples bundle, and script saving/loading. Its definitely the best way to kick the tires!
|
||||
|
||||
We also have a Google Group to make it easy to get help from other CadQuery users. Please join the group and introduce yourself, and we would also love to hear what you are doing with CadQuery. https://groups.google.com/forum/#!forum/cadquery
|
||||
|
||||
Examples
|
||||
======================
|
||||
Projects Using CadQuery
|
||||
=========================
|
||||
|
||||
This resin mold was modeled using cadquery and then created on a CNC machine:
|
||||
|
||||
|
@ -143,8 +166,6 @@ The cadquery script is surprisingly short, and allows easily customizing any of
|
|||
|
||||
Thanks go to cadquery contributor hyOzd ( Altu Technology ) for the example!
|
||||
|
||||
Projects Using CadQuery
|
||||
=========================
|
||||
|
||||
KiCad uses cadquery to build high quality models of electrictronic components. ( https://github.com/KiCad/packages3D )
|
||||
|
||||
|
@ -166,7 +187,7 @@ The mach30 project used cadquery to develop a tool that will create a rocket thr
|
|||
This example uses Jupyter notebook to produce a really cool web-based scripting environment ( https://github.com/RustyVermeer/avnb/blob/master/readme.md ) :
|
||||
|
||||
<p align="center">
|
||||
<img src="https://github.com/RustyVermeer/avnb/raw/master/example.gif" width="700"/>
|
||||
<img src="https://github.com/RustyVermeer/cqnb/raw/master/showcase.gif" width="350"/>
|
||||
</p>
|
||||
|
||||
|
||||
|
@ -176,7 +197,19 @@ This example uses Jupyter notebook to produce a really cool web-based scripting
|
|||
We would love to link to your cadquery based project. Just let us know and we'll add it here.
|
||||
|
||||
|
||||
Where does the name CadQuery come from?
|
||||
========================================
|
||||
|
||||
CadQuery is inspired by jQuery, a popular framework that
|
||||
revolutionized web development involving javascript.
|
||||
|
||||
If you are familiar with jQuery, you will probably recognize several jQuery features that CadQuery uses:
|
||||
|
||||
* A fluent api to create clean, easy to read code
|
||||
* Language features that make selection and iteration incredibly easy
|
||||
*
|
||||
* Ability to use the library along side other python libraries
|
||||
* Clear and complete documentation, with plenty of samples.
|
||||
|
||||
Why CadQuery instead of OpenSCAD?
|
||||
========================================
|
||||
|
@ -208,74 +241,17 @@ License
|
|||
CadQuery is licensed under the terms of the Apache Public License, version 2.0.
|
||||
A copy of the license can be found at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
CadQuery GUI Interfaces
|
||||
=======================
|
||||
Ongoing and Future Work
|
||||
============
|
||||
|
||||
There are currently several known CadQuery GUIs:
|
||||
|
||||
### CadQuery FreeCAD Module
|
||||
You can use CadQuery inside of FreeCAD. There's an excellent plugin module here https://github.com/jmwright/cadquery-freecad-module
|
||||
|
||||
### CadQuery GUI (under active development)
|
||||
### CadQuery GUI (under development)
|
||||
Work is underway on a stand-alone gui here: https://github.com/jmwright/cadquery-gui
|
||||
|
||||
### ParametricParts.com
|
||||
If you are impatient and want to see a working example with no installation, have a look at this lego brick example http://parametricparts.com/parts/vqb5dy69/.
|
||||
### CadQuery Parts / Assembly Handling
|
||||
Work by Fragmuffin is ongoing with the [cqparts](https://github.com/fragmuffin/cqparts) repo.
|
||||
|
||||
The script that generates the model is on the 'modelscript' tab.
|
||||
|
||||
|
||||
Installing -- FreeStanding Installation
|
||||
========================================
|
||||
|
||||
Use these steps if you would like to write CadQuery scripts as a python API. In this case, FreeCAD is used only as a CAD kernel.
|
||||
|
||||
1. install FreeCAD, version 0.15 or greater for your platform. https://github.com/FreeCAD/FreeCAD/releases.
|
||||
|
||||
2. adjust your path if necessary. FreeCAD bundles a python interpreter, but you'll probably want to use your own,
|
||||
preferably one that has virtualenv available. To use FreeCAD from any python interpreter, just append the FreeCAD
|
||||
lib directory to your path. On (*Nix)::
|
||||
|
||||
```python
|
||||
import sys
|
||||
sys.path.append('/usr/lib/freecad/lib')
|
||||
```
|
||||
|
||||
or on Windows::
|
||||
|
||||
```python
|
||||
import sys
|
||||
sys.path.append('/c/apps/FreeCAD/bin')
|
||||
```
|
||||
|
||||
*NOTE* FreeCAD on Windows will not work with python 2.7-- you must use pthon 2.6.X!!!!
|
||||
|
||||
3. install cadquery::
|
||||
```bash
|
||||
pip install cadquery
|
||||
```
|
||||
4. installing cadquery should install pyparsing as well, but if not::
|
||||
```bash
|
||||
pip install pyparsing
|
||||
```
|
||||
5. test your installation::
|
||||
```python
|
||||
from cadquery import *
|
||||
box = Workplane("XY").box(1,2,3)
|
||||
exporters.toString(box,'STL')
|
||||
```
|
||||
You're up and running!
|
||||
|
||||
Installing -- Using CadQuery from Inside FreeCAD
|
||||
=================================================
|
||||
|
||||
Use the CadQuery module for FreeCAD here:
|
||||
https://github.com/jmwright/cadquery-freecad-module
|
||||
|
||||
It includes a distribution of the latest version of cadquery.
|
||||
|
||||
Roadmap/Future Work
|
||||
=======================
|
||||
### Moving to Python3 and away from FreeCAD as a dependency
|
||||
Adam Urbańczyk has been working hard on his own [CQ fork](https://github.com/adam-urbanczyk/cadquery) which uses only PythonOCC instead of FreeCAD.
|
||||
|
||||
Work has begun on Cadquery 2.0, which will feature:
|
||||
|
||||
|
@ -286,17 +262,3 @@ Work has begun on Cadquery 2.0, which will feature:
|
|||
The project page can be found here: https://github.com/dcowden/cadquery/projects/1
|
||||
|
||||
A more detailed description of the plan for CQ 2.0 is here: https://docs.google.com/document/d/1cXuxBkVeYmGOo34MGRdG7E3ILypQqkrJ26oVf3CUSPQ
|
||||
|
||||
Where does the name CadQuery come from?
|
||||
========================================
|
||||
|
||||
CadQuery is inspired by jQuery, a popular framework that
|
||||
revolutionized web development involving javascript.
|
||||
|
||||
If you are familiar with how jQuery, you will probably recognize several jQuery features that CadQuery uses:
|
||||
|
||||
* A fluent api to create clean, easy to read code
|
||||
* Language features that make selection and iteration incredibly easy
|
||||
*
|
||||
* Ability to use the library along side other python libraries
|
||||
* Clear and complete documentation, with plenty of samples.
|
||||
|
|
|
@ -12,7 +12,7 @@ cp examples/FreeCAD/Ex001_Simple_Block.py $CQ_TEST_DIR
|
|||
|
||||
|
||||
fail_test( ){
|
||||
"Test Failed."
|
||||
echo "Test Failed."
|
||||
}
|
||||
|
||||
echo "Running Tests..."
|
||||
|
|
|
@ -23,6 +23,8 @@ from cadquery import *
|
|||
from cadquery import selectors
|
||||
from cadquery import exporters
|
||||
|
||||
from copy import copy, deepcopy
|
||||
|
||||
|
||||
class CQContext(object):
|
||||
"""
|
||||
|
@ -75,7 +77,7 @@ class CQ(object):
|
|||
Custom plugins and subclasses should use this method to create new CQ objects
|
||||
correctly.
|
||||
"""
|
||||
r = CQ(None) # create a completely blank one
|
||||
r = type(self)(None) # create a completely blank one
|
||||
r.parent = self
|
||||
r.ctx = self.ctx # context solid remains the same
|
||||
r.objects = list(objlist)
|
||||
|
@ -237,7 +239,7 @@ class CQ(object):
|
|||
"""
|
||||
if type(obj) == list:
|
||||
self.objects.extend(obj)
|
||||
elif type(obj) == CQ or type(obj) == Workplane:
|
||||
elif isinstance(obj, CQ):
|
||||
self.objects.extend(obj.objects)
|
||||
else:
|
||||
self.objects.append(obj)
|
||||
|
@ -479,9 +481,10 @@ class CQ(object):
|
|||
toReturn = self._collectProperty(objType)
|
||||
|
||||
if selector is not None:
|
||||
if isinstance(selector, str) or isinstance(selector, str):
|
||||
# if isinstance(selector, str) or isinstance(selector, str):
|
||||
try:
|
||||
selectorObj = selectors.StringSyntaxSelector(selector)
|
||||
else:
|
||||
except:
|
||||
selectorObj = selector
|
||||
toReturn = selectorObj.filter(toReturn)
|
||||
|
||||
|
@ -668,7 +671,7 @@ class CQ(object):
|
|||
"""
|
||||
return self._selectObjects('Compounds', selector)
|
||||
|
||||
def toSvg(self, opts=None):
|
||||
def toSvg(self, opts=None, view_vector=(-1.75,1.1,5)):
|
||||
"""
|
||||
Returns svg text that represents the first item on the stack.
|
||||
|
||||
|
@ -676,20 +679,26 @@ class CQ(object):
|
|||
|
||||
:param opts: svg formatting options
|
||||
:type opts: dictionary, width and height
|
||||
|
||||
:param view_vector: camera's view direction vector
|
||||
:type view_vector: tuple, (x, y, z)
|
||||
:return: a string that contains SVG that represents this item.
|
||||
"""
|
||||
return exporters.getSVG(self.val().wrapped, opts)
|
||||
return exporters.getSVG(self.val().wrapped, opts=opts, view_vector=view_vector)
|
||||
|
||||
def exportSvg(self, fileName):
|
||||
def exportSvg(self, fileName, view_vector=(-1.75,1.1,5)):
|
||||
"""
|
||||
Exports the first item on the stack as an SVG file
|
||||
|
||||
For testing purposes mainly.
|
||||
|
||||
:param fileName: the filename to export
|
||||
|
||||
:param view_vector: camera's view direction vector
|
||||
:type view_vector: tuple, (x, y, z)
|
||||
:type fileName: String, absolute path to the file
|
||||
"""
|
||||
exporters.exportSVG(self, fileName)
|
||||
exporters.exportSVG(self, fileName, view_vector)
|
||||
|
||||
def rotateAboutCenter(self, axisEndPoint, angleDegrees):
|
||||
"""
|
||||
|
@ -745,7 +754,7 @@ class CQ(object):
|
|||
def mirror(self, mirrorPlane="XY", basePointVector=(0, 0, 0)):
|
||||
"""
|
||||
Mirror a single CQ object. This operation is the same as in the FreeCAD PartWB's mirroring
|
||||
|
||||
|
||||
:param mirrorPlane: the plane to mirror about
|
||||
:type mirrorPlane: string, one of "XY", "YX", "XZ", "ZX", "YZ", "ZY" the planes
|
||||
:param basePointVector: the base point to mirror about
|
||||
|
@ -882,6 +891,12 @@ class CQ(object):
|
|||
solid.wrapped = s.wrapped
|
||||
return self.newObject([s])
|
||||
|
||||
def __copy__(self):
|
||||
return self.newObject(copy(self.objects))
|
||||
|
||||
def __deepcopy__(self, memo):
|
||||
return self.newObject(deepcopy(self.objects, memo))
|
||||
|
||||
|
||||
class Workplane(CQ):
|
||||
"""
|
||||
|
@ -935,10 +950,11 @@ class Workplane(CQ):
|
|||
|
||||
if inPlane.__class__.__name__ == 'Plane':
|
||||
tmpPlane = inPlane
|
||||
elif isinstance(inPlane, str) or isinstance(inPlane, str):
|
||||
tmpPlane = Plane.named(inPlane, origin)
|
||||
else:
|
||||
tmpPlane = None
|
||||
try:
|
||||
tmpPlane = Plane.named(inPlane, origin)
|
||||
except ValueError:
|
||||
tmpPlane = None
|
||||
|
||||
if tmpPlane is None:
|
||||
raise ValueError(
|
||||
|
@ -991,7 +1007,7 @@ class Workplane(CQ):
|
|||
"""
|
||||
|
||||
#copy the current state to the new object
|
||||
ns = Workplane("XY")
|
||||
ns = type(self)("XY")
|
||||
ns.plane = self.plane
|
||||
ns.parent = self
|
||||
ns.objects = list(objlist)
|
||||
|
@ -2123,7 +2139,7 @@ class Workplane(CQ):
|
|||
"""
|
||||
|
||||
#first collect all of the items together
|
||||
if type(toUnion) == CQ or type(toUnion) == Workplane:
|
||||
if isinstance(toUnion, CQ):
|
||||
solids = toUnion.solids().vals()
|
||||
if len(solids) < 1:
|
||||
raise ValueError("CQ object must have at least one solid on the stack to union!")
|
||||
|
|
|
@ -139,8 +139,8 @@ class ShapeResult(object):
|
|||
"""
|
||||
def __init__(self):
|
||||
self.shape = None
|
||||
self.options = None
|
||||
|
||||
self.options = None
|
||||
|
||||
class BuildResult(object):
|
||||
"""
|
||||
The result of executing a CadQuery script.
|
||||
|
@ -253,7 +253,6 @@ class InputParameter:
|
|||
return p
|
||||
|
||||
def set_value(self, new_value):
|
||||
|
||||
if len(self.valid_values) > 0 and new_value not in self.valid_values:
|
||||
raise InvalidParameterError(
|
||||
"Cannot set value '{0:s}' for parameter '{1:s}': not a valid value. Valid values are {2:s} "
|
||||
|
@ -277,9 +276,15 @@ class InputParameter:
|
|||
self.ast_node.s = str(new_value)
|
||||
elif self.varType == BooleanParameterType:
|
||||
if new_value:
|
||||
self.ast_node.id = 'True'
|
||||
if hasattr(ast, 'NameConstant'):
|
||||
self.ast_node.value = True
|
||||
else:
|
||||
self.ast_node.id = 'True'
|
||||
else:
|
||||
self.ast_node.id = 'False'
|
||||
if hasattr(ast, 'NameConstant'):
|
||||
self.ast_node.value = False
|
||||
else:
|
||||
self.ast_node.id = 'False'
|
||||
else:
|
||||
raise ValueError("Unknown Type of var: ", str(self.varType))
|
||||
|
||||
|
@ -449,13 +454,20 @@ class ConstantAssignmentFinder(ast.NodeTransformer):
|
|||
elif type(value_node) == ast.Str:
|
||||
self.cqModel.add_script_parameter(
|
||||
InputParameter.create(value_node, var_name, StringParameterType, value_node.s))
|
||||
elif type(value_node == ast.Name):
|
||||
elif type(value_node) == ast.Name:
|
||||
if value_node.id == 'True':
|
||||
self.cqModel.add_script_parameter(
|
||||
InputParameter.create(value_node, var_name, BooleanParameterType, True))
|
||||
elif value_node.id == 'False':
|
||||
self.cqModel.add_script_parameter(
|
||||
InputParameter.create(value_node, var_name, BooleanParameterType, False))
|
||||
elif hasattr(ast, 'NameConstant') and type(value_node) == ast.NameConstant:
|
||||
if value_node.value == True:
|
||||
self.cqModel.add_script_parameter(
|
||||
InputParameter.create(value_node, var_name, BooleanParameterType, True))
|
||||
else:
|
||||
self.cqModel.add_script_parameter(
|
||||
InputParameter.create(value_node, var_name, BooleanParameterType, False))
|
||||
except:
|
||||
print("Unable to handle assignment for variable '%s'" % var_name)
|
||||
pass
|
||||
|
@ -469,7 +481,12 @@ class ConstantAssignmentFinder(ast.NodeTransformer):
|
|||
if isinstance(left_side,ast.Attribute):
|
||||
return
|
||||
|
||||
if type(node.value) in [ast.Num, ast.Str, ast.Name]:
|
||||
# Handle the NamedConstant type that is only present in Python 3
|
||||
astTypes = [ast.Num, ast.Str, ast.Name]
|
||||
if hasattr(ast, 'NameConstant'):
|
||||
astTypes.append(ast.NameConstant)
|
||||
|
||||
if type(node.value) in astTypes:
|
||||
self.handle_assignment(left_side.id, node.value)
|
||||
elif type(node.value) == ast.Tuple:
|
||||
# we have a multi-value assignment
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
import cadquery
|
||||
|
||||
import FreeCAD
|
||||
|
@ -82,11 +84,11 @@ def exportShape(shape,exportType,fileLike,tolerance=0.1):
|
|||
if exportType == ExportTypes.STEP:
|
||||
shape.exportStep(outFileName)
|
||||
elif exportType == ExportTypes.STL:
|
||||
shape.wrapped.exportStl(outFileName)
|
||||
shape.wrapped.exportStl(outFileName,tolerance)
|
||||
else:
|
||||
raise ValueError("No idea how i got here")
|
||||
|
||||
res = readAndDeleteFile(outFileName)
|
||||
res = '{}'.format(readAndDeleteFile(outFileName))
|
||||
fileLike.write(res)
|
||||
|
||||
def readAndDeleteFile(fileName):
|
||||
|
@ -94,7 +96,7 @@ def readAndDeleteFile(fileName):
|
|||
read data from file provided, and delete it when done
|
||||
return the contents as a string
|
||||
"""
|
||||
res = ""
|
||||
res = ''
|
||||
with open(fileName,'r') as f:
|
||||
res = f.read()
|
||||
|
||||
|
@ -159,7 +161,7 @@ class AmfWriter(object):
|
|||
v3 = ET.SubElement(triangle,'v3')
|
||||
v3.text = str(t[2])
|
||||
|
||||
ET.ElementTree(amf).write(outFile,encoding="unicode",xml_declaration=True)
|
||||
ET.ElementTree(amf).write(outFile,xml_declaration=True)
|
||||
|
||||
"""
|
||||
Objects that represent
|
||||
|
@ -169,20 +171,20 @@ class AmfWriter(object):
|
|||
class JsonMesh(object):
|
||||
def __init__(self):
|
||||
|
||||
self.vertices = [];
|
||||
self.faces = [];
|
||||
self.nVertices = 0;
|
||||
self.nFaces = 0;
|
||||
self.vertices = []
|
||||
self.faces = []
|
||||
self.nVertices = 0
|
||||
self.nFaces = 0
|
||||
|
||||
def addVertex(self,x,y,z):
|
||||
self.nVertices += 1;
|
||||
self.vertices.extend([x,y,z]);
|
||||
def addVertex(self, x, y, z):
|
||||
self.nVertices += 1
|
||||
self.vertices.extend([x,y,z])
|
||||
|
||||
#add triangle composed of the three provided vertex indices
|
||||
def addTriangleFace(self, i,j,k):
|
||||
def addTriangleFace(self, i, j, k):
|
||||
#first position means justa simple triangle
|
||||
self.nFaces += 1;
|
||||
self.faces.extend([0,int(i),int(j),int(k)]);
|
||||
self.nFaces += 1
|
||||
self.faces.extend([0, int(i), int(j), int(k)])
|
||||
|
||||
"""
|
||||
Get a json model from this model.
|
||||
|
@ -193,7 +195,7 @@ class JsonMesh(object):
|
|||
'vertices' : str(self.vertices),
|
||||
'faces' : str(self.faces),
|
||||
'nVertices': self.nVertices,
|
||||
'nFaces' : self.nFaces
|
||||
'nFaces': self.nFaces,
|
||||
};
|
||||
|
||||
|
||||
|
@ -234,11 +236,11 @@ def getPaths(freeCadSVG):
|
|||
return ([],[])
|
||||
|
||||
|
||||
def getSVG(shape,opts=None):
|
||||
def getSVG(shape, opts=None, view_vector=(-1.75, 1.1, 5.0)):
|
||||
"""
|
||||
Export a shape to SVG
|
||||
"""
|
||||
|
||||
|
||||
d = {'width':800,'height':240,'marginLeft':200,'marginTop':20}
|
||||
|
||||
if opts:
|
||||
|
@ -253,7 +255,7 @@ def getSVG(shape,opts=None):
|
|||
marginTop=float(d['marginTop'])
|
||||
|
||||
#TODO: provide option to give 3 views
|
||||
viewVector = FreeCAD.Base.Vector(-1.75,1.1,5)
|
||||
viewVector = FreeCAD.Base.Vector(view_vector)
|
||||
(visibleG0,visibleG1,hiddenG0,hiddenG1) = Drawing.project(shape,viewVector)
|
||||
|
||||
(hiddenPaths,visiblePaths) = getPaths(Drawing.projectToSVG(shape,viewVector,"ShowHiddenLines")) #this param is totally undocumented!
|
||||
|
@ -281,16 +283,16 @@ def getSVG(shape,opts=None):
|
|||
|
||||
svg = SVG_TEMPLATE % (
|
||||
{
|
||||
"unitScale" : str(unitScale),
|
||||
"strokeWidth" : str(1.0/unitScale),
|
||||
"hiddenContent" : hiddenContent ,
|
||||
"visibleContent" :visibleContent,
|
||||
"xTranslate" : str(xTranslate),
|
||||
"yTranslate" : str(yTranslate),
|
||||
"width" : str(width),
|
||||
"height" : str(height),
|
||||
"textboxY" :str(height - 30),
|
||||
"uom" : str(uom)
|
||||
'unitScale': str(unitScale),
|
||||
'strokeWidth': str(1.0 / unitScale),
|
||||
'hiddenContent': hiddenContent ,
|
||||
'visibleContent': visibleContent,
|
||||
'xTranslate': str(xTranslate),
|
||||
'yTranslate': str(yTranslate),
|
||||
'width': str(width),
|
||||
'height': str(height),
|
||||
'textboxY': str(height - 30),
|
||||
'uom': str(uom)
|
||||
}
|
||||
)
|
||||
#svg = SVG_TEMPLATE % (
|
||||
|
@ -299,14 +301,13 @@ def getSVG(shape,opts=None):
|
|||
return svg
|
||||
|
||||
|
||||
def exportSVG(shape, fileName):
|
||||
def exportSVG(shape, fileName, view_vector=(-1.75,1.1,5)):
|
||||
"""
|
||||
accept a cadquery shape, and export it to the provided file
|
||||
TODO: should use file-like objects, not a fileName, and/or be able to return a string instead
|
||||
export a view of a part to svg
|
||||
"""
|
||||
|
||||
svg = getSVG(shape.val().wrapped)
|
||||
svg = getSVG(shape.val().wrapped, opts=None, view_vector=view_vector)
|
||||
f = open(fileName,'w')
|
||||
f.write(svg)
|
||||
f.close()
|
||||
|
@ -376,20 +377,6 @@ SVG_TEMPLATE = """<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|||
%(visibleContent)s
|
||||
</g>
|
||||
</g>
|
||||
<g transform="translate(20,%(textboxY)s)" stroke="rgb(0,0,255)">
|
||||
<line x1="30" y1="-30" x2="75" y2="-33" stroke-width="3" stroke="#000000" />
|
||||
<text x="80" y="-30" style="stroke:#000000">X </text>
|
||||
|
||||
<line x1="30" y1="-30" x2="30" y2="-75" stroke-width="3" stroke="#000000" />
|
||||
<text x="25" y="-85" style="stroke:#000000">Y </text>
|
||||
|
||||
<line x1="30" y1="-30" x2="58" y2="-15" stroke-width="3" stroke="#000000" />
|
||||
<text x="65" y="-5" style="stroke:#000000">Z </text>
|
||||
<!--
|
||||
<line x1="0" y1="0" x2="%(unitScale)s" y2="0" stroke-width="3" />
|
||||
<text x="0" y="20" style="stroke:#000000">1 %(uom)s </text>
|
||||
-->
|
||||
</g>
|
||||
</svg>
|
||||
"""
|
||||
|
||||
|
|
|
@ -16,8 +16,9 @@
|
|||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; If not, see <http://www.gnu.org/licenses/>
|
||||
"""
|
||||
|
||||
from __future__ import division
|
||||
import math
|
||||
from copy import copy
|
||||
import cadquery
|
||||
import FreeCAD
|
||||
import Part as FreeCADPart
|
||||
|
@ -58,92 +59,134 @@ def sortWiresByBuildOrder(wireList, plane, result=[]):
|
|||
class Vector(object):
|
||||
"""Create a 3-dimensional vector
|
||||
|
||||
:param args: a 3-d vector, with x-y-z parts.
|
||||
**you can provide any of:**
|
||||
|
||||
you can either provide:
|
||||
* nothing (in which case the null vector is return)
|
||||
* a FreeCAD vector
|
||||
* a vector ( in which case it is copied )
|
||||
* a 3-tuple
|
||||
* three float values, x, y, and z
|
||||
* nothing (in which case a zero vector is return)
|
||||
* a :class:`FreeCAD.Base.Vector` instance to wrap
|
||||
* a :class:`Vector` (in which case it is copied)
|
||||
* a 2-tuple of :class:`float`, ``(x, y)`` (z=0)
|
||||
* a 3-tuple of :class:`float`, ``(x, y, z)``
|
||||
* 2 :class:`float` values, as ``x``, and ``y``
|
||||
* 3 :class:`float` values, as ``x``, ``y``, and ``z``
|
||||
* named coordinates, like ``Vector(x=1, z=2)``
|
||||
|
||||
.. doctest::
|
||||
|
||||
>>> from cadquery import Vector
|
||||
>>> import FreeCAD
|
||||
>>> Vector()
|
||||
Vector (0.0, 0.0, 0.0)
|
||||
>>> Vector(FreeCAD.Base.Vector(1,2,3))
|
||||
Vector (1.0, 2.0, 3.0)
|
||||
>>> Vector(Vector(4,5,6))
|
||||
Vector (4.0, 5.0, 6.0)
|
||||
>>> Vector((1, 2))
|
||||
Vector (1.0, 2.0, 0.0)
|
||||
>>> Vector((1, 2, 3))
|
||||
Vector (1.0, 2.0, 3.0)
|
||||
>>> Vector(4, 5)
|
||||
Vector (4.0, 5.0, 0.0)
|
||||
>>> Vector(4, 5, 6)
|
||||
Vector (4.0, 5.0, 6.0)
|
||||
>>> Vector(x=1, z=2)
|
||||
Vector (1.0, 0.0, 2.0)
|
||||
"""
|
||||
def __init__(self, *args):
|
||||
if len(args) == 3:
|
||||
fV = FreeCAD.Base.Vector(args[0], args[1], args[2])
|
||||
elif len(args) == 1:
|
||||
if isinstance(args[0], Vector):
|
||||
fV = args[0].wrapped
|
||||
elif isinstance(args[0], tuple):
|
||||
fV = FreeCAD.Base.Vector(args[0][0], args[0][1], args[0][2])
|
||||
elif isinstance(args[0], FreeCAD.Base.Vector):
|
||||
fV = args[0]
|
||||
def __init__(self, *args, **kwargs):
|
||||
fV = None
|
||||
|
||||
if args and not kwargs:
|
||||
if (1 <= len(args) <= 3): # 1, 2, or 3 arguments (no keyword arguments given)
|
||||
if isinstance(args[0], (int, float)):
|
||||
# First argument is a number, pass list through to freecad
|
||||
fV = FreeCAD.Base.Vector(*args)
|
||||
elif len(args) == 1:
|
||||
arg = args[0] # only 1 argument given
|
||||
if isinstance(arg, Vector):
|
||||
v = arg.wrapped
|
||||
fV = FreeCAD.Base.Vector(v.x, v.y, v.z) # create copy
|
||||
elif isinstance(arg, FreeCAD.Base.Vector):
|
||||
v = arg
|
||||
fV = FreeCAD.Base.Vector(v.x, v.y, v.z) # create copy
|
||||
elif isinstance(arg, (list, tuple)):
|
||||
if (1 <= len(arg) <= 3):
|
||||
fV = FreeCAD.Base.Vector(*arg)
|
||||
elif not args:
|
||||
if set(kwargs.keys()) - set('xyz'):
|
||||
pass # kwargs contains invalid arguments, raise exception
|
||||
else:
|
||||
fV = args[0]
|
||||
elif len(args) == 0:
|
||||
fV = FreeCAD.Base.Vector(0, 0, 0)
|
||||
else:
|
||||
raise ValueError("Expected three floats, FreeCAD Vector, or 3-tuple")
|
||||
fV = FreeCAD.Base.Vector(
|
||||
kwargs.get('x', 0),
|
||||
kwargs.get('y', 0),
|
||||
kwargs.get('z', 0),
|
||||
)
|
||||
|
||||
if fV is None:
|
||||
raise ValueError(
|
||||
"Expected 2 or 3 floats, FreeCAD Vector, 2 or 3-tuple, or named lower-case coords. " + \
|
||||
("%r %r" % (args, kwargs))
|
||||
)
|
||||
|
||||
self._wrapped = fV
|
||||
|
||||
@property
|
||||
def x(self):
|
||||
return self.wrapped.x
|
||||
return self._wrapped.x
|
||||
|
||||
@x.setter
|
||||
def x(self, value):
|
||||
self.wrapped.x = value
|
||||
self._wrapped.x = value
|
||||
|
||||
@property
|
||||
def y(self):
|
||||
return self.wrapped.y
|
||||
return self._wrapped.y
|
||||
|
||||
@y.setter
|
||||
def y(self, value):
|
||||
self.wrapped.y = value
|
||||
self._wrapped.y = value
|
||||
|
||||
@property
|
||||
def z(self):
|
||||
return self.wrapped.z
|
||||
return self._wrapped.z
|
||||
|
||||
@z.setter
|
||||
def z(self, value):
|
||||
self.wrapped.z = value
|
||||
self._wrapped.z = value
|
||||
|
||||
@property
|
||||
def Length(self):
|
||||
return self.wrapped.Length
|
||||
return self._wrapped.Length
|
||||
|
||||
@property
|
||||
def wrapped(self):
|
||||
return self._wrapped
|
||||
|
||||
def toTuple(self):
|
||||
return (self.x, self.y, self.z)
|
||||
v = self._wrapped
|
||||
return (v.x, v.y, v.z)
|
||||
|
||||
# TODO: is it possible to create a dynamic proxy without all this code?
|
||||
def cross(self, v):
|
||||
return Vector(self.wrapped.cross(v.wrapped))
|
||||
return type(self)(self._wrapped.cross(v.wrapped))
|
||||
|
||||
def dot(self, v):
|
||||
return self.wrapped.dot(v.wrapped)
|
||||
return self._wrapped.dot(v.wrapped)
|
||||
|
||||
def sub(self, v):
|
||||
return Vector(self.wrapped.sub(v.wrapped))
|
||||
return type(self)(self._wrapped.sub(v.wrapped))
|
||||
|
||||
def add(self, v):
|
||||
return Vector(self.wrapped.add(v.wrapped))
|
||||
return type(self)(self._wrapped.add(v.wrapped))
|
||||
|
||||
def multiply(self, scale):
|
||||
"""Return a copy multiplied by the provided scalar"""
|
||||
tmp_fc_vector = FreeCAD.Base.Vector(self.wrapped)
|
||||
return Vector(tmp_fc_vector.multiply(scale))
|
||||
tmp_fc_vector = FreeCAD.Base.Vector(self._wrapped)
|
||||
return type(self)(tmp_fc_vector.multiply(scale))
|
||||
|
||||
def normalized(self):
|
||||
"""Return a normalized version of this vector"""
|
||||
tmp_fc_vector = FreeCAD.Base.Vector(self.wrapped)
|
||||
tmp_fc_vector = FreeCAD.Base.Vector(self._wrapped)
|
||||
tmp_fc_vector.normalize()
|
||||
return Vector(tmp_fc_vector)
|
||||
return type(self)(tmp_fc_vector)
|
||||
|
||||
def Center(self):
|
||||
"""Return the vector itself
|
||||
|
@ -156,7 +199,7 @@ class Vector(object):
|
|||
return self
|
||||
|
||||
def getAngle(self, v):
|
||||
return self.wrapped.getAngle(v.wrapped)
|
||||
return self._wrapped.getAngle(v.wrapped)
|
||||
|
||||
def distanceToLine(self):
|
||||
raise NotImplementedError("Have not needed this yet, but FreeCAD supports it!")
|
||||
|
@ -170,17 +213,36 @@ class Vector(object):
|
|||
def projectToPlane(self):
|
||||
raise NotImplementedError("Have not needed this yet, but FreeCAD supports it!")
|
||||
|
||||
def __bool__(self):
|
||||
return any(coord != 0 for coord in self.toTuple())
|
||||
|
||||
__nonzero__ = __bool__ # python 2.x compatability
|
||||
|
||||
def __add__(self, v):
|
||||
return self.add(v)
|
||||
|
||||
def __sub__(self, v):
|
||||
return self.sub(v)
|
||||
|
||||
def __mul__(self, scalar):
|
||||
return self.multiply(scalar)
|
||||
|
||||
def __truediv__(self, scalar):
|
||||
if scalar == 0:
|
||||
raise ZeroDivisionError("%r division by zero" % (type(self)))
|
||||
return self.multiply(1. / scalar)
|
||||
|
||||
def __neg__(self):
|
||||
return type(self)(self.wrapped.negative())
|
||||
|
||||
def __abs__(self):
|
||||
return self.Length
|
||||
|
||||
def __repr__(self):
|
||||
return self.wrapped.__repr__()
|
||||
return self._wrapped.__repr__()
|
||||
|
||||
def __str__(self):
|
||||
return self.wrapped.__str__()
|
||||
return self._wrapped.__str__()
|
||||
|
||||
def __ne__(self, other):
|
||||
if isinstance(other, Vector):
|
||||
|
@ -192,6 +254,9 @@ class Vector(object):
|
|||
return self.wrapped.__eq__(other.wrapped)
|
||||
return False
|
||||
|
||||
def __copy__(self):
|
||||
return type(self)(self._wrapped)
|
||||
|
||||
|
||||
class Matrix:
|
||||
"""A 3d , 4x4 transformation matrix.
|
||||
|
@ -224,6 +289,10 @@ class Plane(object):
|
|||
created automatically from faces.
|
||||
"""
|
||||
|
||||
# equality tolerances
|
||||
_eq_tolerance_origin = 1e-6
|
||||
_eq_tolerance_dot = 1e-6
|
||||
|
||||
@classmethod
|
||||
def named(cls, stdName, origin=(0, 0, 0)):
|
||||
"""Create a predefined Plane based on the conventional names.
|
||||
|
@ -256,18 +325,18 @@ class Plane(object):
|
|||
|
||||
namedPlanes = {
|
||||
# origin, xDir, normal
|
||||
'XY': Plane(origin, (1, 0, 0), (0, 0, 1)),
|
||||
'YZ': Plane(origin, (0, 1, 0), (1, 0, 0)),
|
||||
'ZX': Plane(origin, (0, 0, 1), (0, 1, 0)),
|
||||
'XZ': Plane(origin, (1, 0, 0), (0, -1, 0)),
|
||||
'YX': Plane(origin, (0, 1, 0), (0, 0, -1)),
|
||||
'ZY': Plane(origin, (0, 0, 1), (-1, 0, 0)),
|
||||
'front': Plane(origin, (1, 0, 0), (0, 0, 1)),
|
||||
'back': Plane(origin, (-1, 0, 0), (0, 0, -1)),
|
||||
'left': Plane(origin, (0, 0, 1), (-1, 0, 0)),
|
||||
'right': Plane(origin, (0, 0, -1), (1, 0, 0)),
|
||||
'top': Plane(origin, (1, 0, 0), (0, 1, 0)),
|
||||
'bottom': Plane(origin, (1, 0, 0), (0, -1, 0))
|
||||
'XY': cls(origin, (1, 0, 0), (0, 0, 1)),
|
||||
'YZ': cls(origin, (0, 1, 0), (1, 0, 0)),
|
||||
'ZX': cls(origin, (0, 0, 1), (0, 1, 0)),
|
||||
'XZ': cls(origin, (1, 0, 0), (0, -1, 0)),
|
||||
'YX': cls(origin, (0, 1, 0), (0, 0, -1)),
|
||||
'ZY': cls(origin, (0, 0, 1), (-1, 0, 0)),
|
||||
'front': cls(origin, (1, 0, 0), (0, 0, 1)),
|
||||
'back': cls(origin, (-1, 0, 0), (0, 0, -1)),
|
||||
'left': cls(origin, (0, 0, 1), (-1, 0, 0)),
|
||||
'right': cls(origin, (0, 0, -1), (1, 0, 0)),
|
||||
'top': cls(origin, (1, 0, 0), (0, 1, 0)),
|
||||
'bottom': cls(origin, (1, 0, 0), (0, -1, 0))
|
||||
}
|
||||
|
||||
try:
|
||||
|
@ -278,73 +347,73 @@ class Plane(object):
|
|||
|
||||
@classmethod
|
||||
def XY(cls, origin=(0, 0, 0), xDir=Vector(1, 0, 0)):
|
||||
plane = Plane.named('XY', origin)
|
||||
plane = cls.named('XY', origin)
|
||||
plane._setPlaneDir(xDir)
|
||||
return plane
|
||||
|
||||
@classmethod
|
||||
def YZ(cls, origin=(0, 0, 0), xDir=Vector(0, 1, 0)):
|
||||
plane = Plane.named('YZ', origin)
|
||||
plane = cls.named('YZ', origin)
|
||||
plane._setPlaneDir(xDir)
|
||||
return plane
|
||||
|
||||
@classmethod
|
||||
def ZX(cls, origin=(0, 0, 0), xDir=Vector(0, 0, 1)):
|
||||
plane = Plane.named('ZX', origin)
|
||||
plane = cls.named('ZX', origin)
|
||||
plane._setPlaneDir(xDir)
|
||||
return plane
|
||||
|
||||
@classmethod
|
||||
def XZ(cls, origin=(0, 0, 0), xDir=Vector(1, 0, 0)):
|
||||
plane = Plane.named('XZ', origin)
|
||||
plane = cls.named('XZ', origin)
|
||||
plane._setPlaneDir(xDir)
|
||||
return plane
|
||||
|
||||
@classmethod
|
||||
def YX(cls, origin=(0, 0, 0), xDir=Vector(0, 1, 0)):
|
||||
plane = Plane.named('YX', origin)
|
||||
plane = cls.named('YX', origin)
|
||||
plane._setPlaneDir(xDir)
|
||||
return plane
|
||||
|
||||
@classmethod
|
||||
def ZY(cls, origin=(0, 0, 0), xDir=Vector(0, 0, 1)):
|
||||
plane = Plane.named('ZY', origin)
|
||||
plane = cls.named('ZY', origin)
|
||||
plane._setPlaneDir(xDir)
|
||||
return plane
|
||||
|
||||
@classmethod
|
||||
def front(cls, origin=(0, 0, 0), xDir=Vector(1, 0, 0)):
|
||||
plane = Plane.named('front', origin)
|
||||
plane = cls.named('front', origin)
|
||||
plane._setPlaneDir(xDir)
|
||||
return plane
|
||||
|
||||
@classmethod
|
||||
def back(cls, origin=(0, 0, 0), xDir=Vector(-1, 0, 0)):
|
||||
plane = Plane.named('back', origin)
|
||||
plane = cls.named('back', origin)
|
||||
plane._setPlaneDir(xDir)
|
||||
return plane
|
||||
|
||||
@classmethod
|
||||
def left(cls, origin=(0, 0, 0), xDir=Vector(0, 0, 1)):
|
||||
plane = Plane.named('left', origin)
|
||||
plane = cls.named('left', origin)
|
||||
plane._setPlaneDir(xDir)
|
||||
return plane
|
||||
|
||||
@classmethod
|
||||
def right(cls, origin=(0, 0, 0), xDir=Vector(0, 0, -1)):
|
||||
plane = Plane.named('right', origin)
|
||||
plane = cls.named('right', origin)
|
||||
plane._setPlaneDir(xDir)
|
||||
return plane
|
||||
|
||||
@classmethod
|
||||
def top(cls, origin=(0, 0, 0), xDir=Vector(1, 0, 0)):
|
||||
plane = Plane.named('top', origin)
|
||||
plane = cls.named('top', origin)
|
||||
plane._setPlaneDir(xDir)
|
||||
return plane
|
||||
|
||||
@classmethod
|
||||
def bottom(cls, origin=(0, 0, 0), xDir=Vector(1, 0, 0)):
|
||||
plane = Plane.named('bottom', origin)
|
||||
plane = cls.named('bottom', origin)
|
||||
plane._setPlaneDir(xDir)
|
||||
return plane
|
||||
|
||||
|
@ -360,17 +429,30 @@ class Plane(object):
|
|||
:type normal: a FreeCAD Vector
|
||||
:raises: ValueError if the specified xDir is not orthogonal to the provided normal.
|
||||
:return: a plane in the global space, with the xDirection of the plane in the specified direction.
|
||||
|
||||
**Non-orthogonal vectors**
|
||||
|
||||
If the ``xDir`` and ``normal`` vectors are not orthogonal, the ``normal``
|
||||
(or ``z`` axis) vector direction is preserved, and truely orthogonal
|
||||
``x`` and ``y`` axes are calculated with cross products.
|
||||
|
||||
* ``y = z.cross(x)``, and
|
||||
* ``x = y.cross(z)``
|
||||
"""
|
||||
# z-axis
|
||||
normal = Vector(normal)
|
||||
if (normal.Length == 0.0):
|
||||
raise ValueError('normal should be non null')
|
||||
self.zDir = normal.normalized()
|
||||
|
||||
# x-axis
|
||||
xDir = Vector(xDir)
|
||||
if (xDir.Length == 0.0):
|
||||
raise ValueError('xDir should be non null')
|
||||
|
||||
self._setPlaneDir(xDir)
|
||||
|
||||
self.invZDir = self.zDir.multiply(-1.0)
|
||||
self.invZDir = -self.zDir
|
||||
|
||||
self.origin = origin
|
||||
|
||||
|
@ -513,7 +595,7 @@ class Plane(object):
|
|||
newXdir = Vector(m.multiply(self.xDir.wrapped))
|
||||
newZdir = Vector(m.multiply(self.zDir.wrapped))
|
||||
|
||||
return Plane(self.origin, newXdir, newZdir)
|
||||
return type(self)(self.origin, newXdir, newZdir)
|
||||
|
||||
def rotateShapes(self, listOfShapes, rotationMatrix):
|
||||
"""Rotate the listOfShapes by the supplied rotationMatrix
|
||||
|
@ -560,11 +642,9 @@ class Plane(object):
|
|||
|
||||
def _setPlaneDir(self, xDir):
|
||||
"""Set the vectors parallel to the plane, i.e. xDir and yDir"""
|
||||
if (self.zDir.dot(xDir) > 1e-5):
|
||||
raise ValueError('xDir must be parralel to the plane')
|
||||
xDir = Vector(xDir)
|
||||
self.xDir = xDir.normalized()
|
||||
self.xDir = Vector(xDir)
|
||||
self.yDir = self.zDir.cross(self.xDir).normalized()
|
||||
self.xDir = self.yDir.cross(self.zDir).normalized()
|
||||
|
||||
def _calcTransforms(self):
|
||||
"""Computes transformation matrices to convert between coordinates
|
||||
|
@ -596,6 +676,22 @@ class Plane(object):
|
|||
|
||||
return Matrix(self.fG.multiply(tMatrix.wrapped).multiply(self.rG))
|
||||
|
||||
# Equality
|
||||
def __eq__(self, other):
|
||||
def equality_iter():
|
||||
cls = type(self)
|
||||
yield isinstance(other, Plane) # comparison is with another Plane
|
||||
# origins are the same
|
||||
yield abs(self.origin - other.origin) < cls._eq_tolerance_origin
|
||||
# z-axis vectors are parallel (assumption: both are unit vectors)
|
||||
yield abs(self.zDir.dot(other.zDir) - 1) < cls._eq_tolerance_dot
|
||||
# x-axis vectors are parallel (assumption: both are unit vectors)
|
||||
yield abs(self.xDir.dot(other.xDir) - 1) < cls._eq_tolerance_dot
|
||||
return all(equality_iter())
|
||||
|
||||
def __ne__(self, other):
|
||||
return not self.__eq__(other)
|
||||
|
||||
|
||||
class BoundBox(object):
|
||||
"""A BoundingBox for an object or set of objects. Wraps the FreeCAD one"""
|
||||
|
|
|
@ -8,7 +8,7 @@ import sys
|
|||
import os
|
||||
import urllib as urlreader
|
||||
import tempfile
|
||||
|
||||
|
||||
class ImportTypes:
|
||||
STEP = "STEP"
|
||||
|
||||
|
@ -34,10 +34,9 @@ def importStep(fileName):
|
|||
"""
|
||||
Accepts a file name and loads the STEP file into a cadquery shape
|
||||
:param fileName: The path and name of the STEP file to be imported
|
||||
"""
|
||||
"""
|
||||
#Now read and return the shape
|
||||
try:
|
||||
#print fileName
|
||||
rshape = Part.read(fileName)
|
||||
|
||||
#Make sure that we extract all the solids
|
||||
|
@ -50,14 +49,20 @@ def importStep(fileName):
|
|||
raise ValueError("STEP File Could not be loaded")
|
||||
|
||||
#Loads a STEP file from an URL into a CQ.Workplane object
|
||||
def importStepFromURL(url):
|
||||
def importStepFromURL(url):
|
||||
#Now read and return the shape
|
||||
try:
|
||||
webFile = urlreader.urlopen(url)
|
||||
# Account for differences in urllib between Python 2 and 3
|
||||
if hasattr(urlreader, "urlopen"):
|
||||
webFile = urlreader.urlopen(url)
|
||||
else:
|
||||
import urllib.request
|
||||
webFile = urllib.request.urlopen(url)
|
||||
|
||||
tempFile = tempfile.NamedTemporaryFile(suffix='.step', delete=False)
|
||||
tempFile.write(webFile.read())
|
||||
webFile.close()
|
||||
tempFile.close()
|
||||
tempFile.close()
|
||||
|
||||
rshape = Part.read(tempFile.name)
|
||||
|
||||
|
|
|
@ -107,15 +107,15 @@ class Shape(object):
|
|||
# TODO: all these should move into the exporters folder.
|
||||
# we dont need a bunch of exporting code stored in here!
|
||||
#
|
||||
def exportStl(self, fileName):
|
||||
self.wrapped.exportStl(fileName)
|
||||
def exportStl(self, fileName, tolerance=0.1):
|
||||
self.wrapped.exportStl(fileName, tolerance)
|
||||
|
||||
def exportStep(self, fileName):
|
||||
self.wrapped.exportStep(fileName)
|
||||
|
||||
def exportShape(self, fileName, fileFormat):
|
||||
def exportShape(self, fileName, fileFormat, tolerance=0.1):
|
||||
if fileFormat == ExportFormats.STL:
|
||||
self.wrapped.exportStl(fileName)
|
||||
self.wrapped.exportStl(fileName, tolerance)
|
||||
elif fileFormat == ExportFormats.BREP:
|
||||
self.wrapped.exportBrep(fileName)
|
||||
elif fileFormat == ExportFormats.STEP:
|
||||
|
@ -165,7 +165,7 @@ class Shape(object):
|
|||
if the provide object is not a shape at all
|
||||
"""
|
||||
if hasattr(obj, 'ShapeType'):
|
||||
return obj.ShapeType == strType
|
||||
return obj.ShapeType() == strType
|
||||
else:
|
||||
return False
|
||||
|
||||
|
@ -306,7 +306,13 @@ class Shape(object):
|
|||
return [Solid(i) for i in self.wrapped.Solids]
|
||||
|
||||
def Area(self):
|
||||
return self.wrapped.Area
|
||||
"""
|
||||
Returns the area of a shape, but only if it is a face
|
||||
"""
|
||||
if self.wrapped.ShapeType == 'Face':
|
||||
return self.wrapped.Area
|
||||
else:
|
||||
raise ValueError("shape type must be 'Face' to calculate the area")
|
||||
|
||||
def Length(self):
|
||||
return self.wrapped.Length
|
||||
|
@ -650,7 +656,7 @@ class Face(Shape):
|
|||
Create a ruled surface out of two edges or wires. If wires are used then
|
||||
these must have the same
|
||||
"""
|
||||
return Shape.cast(FreeCADPart.makeRuledSurface(edgeOrWire1.obj, edgeOrWire2.obj, dist))
|
||||
return Shape.cast(FreeCADPart.makeRuledSurface(edgeOrWire1.wrapped, edgeOrWire2.wrapped))
|
||||
|
||||
def cut(self, faceToCut):
|
||||
"Remove a face from another one"
|
||||
|
|
|
@ -2,35 +2,72 @@ Changes
|
|||
=======
|
||||
|
||||
|
||||
v0.1
|
||||
-----
|
||||
* Initial Version
|
||||
v1.1.0 (Unreleased)
|
||||
------
|
||||
* Fixes and addition of graphical examples for selectors (thanks @adam-urbanczyk) #181
|
||||
* Added intersect operation (thanks @fragmuffin) #189
|
||||
* CQGI updates (changed `build_object` function name to `show_object`) #194
|
||||
* Added `lefthand` and `heightstyle` options to makeHelix function (thanks @fragmuffin) #197
|
||||
* Test suite cleanup (thanks @fragmuffin) #198
|
||||
* Added formal logging mechanism (thanks @fragmuffin) #200
|
||||
* Merged examples into this library (they were spread out before) #201
|
||||
* Fixed vector equality error (thanks @fragmuffin) #202
|
||||
* Expanded CQGI to handle float variables in addition to int #204
|
||||
* Dockerfile added by @dcowden for Docker build and command line interface #205
|
||||
* Initial Python 3 support for the FreeCAD backend was added by @adam-urbanczyk #207
|
||||
* Fixed Line versus LineSegment incompatibility between FreeCAD 0.16 and 0.17 #209
|
||||
* @RustyVermeer fixed a long-standing bug with the extrusion of invalid faces #210
|
||||
* @adam-urbanczyk fixed a Python 2 versus Python 3 (unicode) issue with SVG export #215
|
||||
|
||||
v1.0.0
|
||||
------
|
||||
* Added an option to do symmetric extrusion about the workplane (thanks @adam-urbanczyk)
|
||||
* Extended selector syntax to include Nth selector and re-implemented selectors using pyparsing (thanks @adam-urbanczyk)
|
||||
* Added logical operations to string selectors (thanks @adam-urbanczyk)
|
||||
* Cleanup of README.md and changes.md (thanks @baoboa)
|
||||
* Fixed bugs with toVector and Face 'Not Defined' errors (thanks @huskier)
|
||||
* Refactor of the initialization code for PEP8 compliance and Python 3 compatibility (thanks @Peque)
|
||||
* Making sure that the new pyparsing library dependency is handled properly (thanks @Peque)
|
||||
|
||||
v0.1.6
|
||||
-----
|
||||
* Added STEP import and supporting tests
|
||||
v0.5.2
|
||||
------
|
||||
* Added the sweep operation #33
|
||||
|
||||
v0.5.1
|
||||
------
|
||||
* Mirroring fixes (thanks @huskier)
|
||||
* Added a mirroring example (thanks @huskier)
|
||||
|
||||
v0.1.7
|
||||
-----
|
||||
* Added revolve operation and supporting tests
|
||||
* Fixed minor documentation errors
|
||||
v0.5.0-stable
|
||||
------
|
||||
* Configuring Travis to push to PyPI on version releases.
|
||||
|
||||
v0.1.8
|
||||
v0.4.1
|
||||
------
|
||||
* Minor CQGI updates
|
||||
|
||||
v0.4.0
|
||||
------
|
||||
* Added Documentation, which is available on dcowden.github.io/cadquery
|
||||
* Added CQGI, an adapter API that standardizes use of cadquery from within structured execution environments
|
||||
* Added ability to import STEP files from a web URL (thanks @huskier ) #128
|
||||
|
||||
v0.3.0
|
||||
-----
|
||||
* Added toFreecad() function as a convenience for val().wrapped
|
||||
* Converted all examples to use toFreecad()
|
||||
* Updated all version numbers that were missed before
|
||||
* Fixed import issues in Windows caused by fc_import
|
||||
* Added/fixed Mac OS support
|
||||
* Improved STEP import
|
||||
* Fixed bug in rotateAboutCenter that negated its effect on solids
|
||||
* Added Travis config (thanks @krasin)
|
||||
* Removed redundant workplane.py file left over from the PParts.com migration
|
||||
* Fixed toWorldCoordinates bug in moveTo (thanks @xix-xeaon)
|
||||
* Added new tests for 2D drawing functions
|
||||
* Integrated Coveralls.io, with a badge in README.md
|
||||
* Integrated version badge in README.md
|
||||
|
||||
* Fixed a bug where clean() could not be called on appropriate objects other than solids (thanks @hyOzd) #108
|
||||
* Implemented new selectors that allow existing selectors to be combined with arithmetic/boolean operations (thanks @hyOzd) #110
|
||||
* Fixed a bug where only 1 random edge was returned with multiple min/max selector matches (thanks @hyOzd) #111
|
||||
* Implemented the creation of a workplane from multiple co-planar faces (thanks @hyOzd) #113
|
||||
* Fixed the operation of Center() when called on a compound with multiple solids
|
||||
* Add the named planes ZX YX ZY to define different normals (thanks @galou) #115
|
||||
* Code cleanup in accordance with PEP 8 (thanks @galou)
|
||||
* Fixed a bug with the close function not resetting the first point of the context correctly (thanks @huskier)
|
||||
* Fixed the findSolid function so that it handles compounds #107
|
||||
* Changed the polyline function so that it adds edges to the stack instead of a wire #102
|
||||
* Add the ability to find the center of the bounding box, rather than the center of mass (thanks @huskier) #122
|
||||
* Changed normalize function to normalized to match OCC/PythonOCC nomenclature #124
|
||||
* Added a label attribute to all freecad_impl.shapes so that they can have IDs attached to them #124
|
||||
|
||||
v0.2.0
|
||||
-----
|
||||
* Fixed versioning to match the semantic versioning scheme
|
||||
|
@ -50,56 +87,31 @@ v0.2.0
|
|||
* Added a clean function to keep some operations from failing on solids that need simplified (thanks @hyOzd)
|
||||
* Added a mention of the new Google Group to the readme
|
||||
|
||||
v0.3.0
|
||||
v0.1.8
|
||||
-----
|
||||
* Fixed a bug where clean() could not be called on appropriate objects other than solids (thanks @hyOzd) #108
|
||||
* Implemented new selectors that allow existing selectors to be combined with arithmetic/boolean operations (thanks @hyOzd) #110
|
||||
* Fixed a bug where only 1 random edge was returned with multiple min/max selector matches (thanks @hyOzd) #111
|
||||
* Implemented the creation of a workplane from multiple co-planar faces (thanks @hyOzd) #113
|
||||
* Fixed the operation of Center() when called on a compound with multiple solids
|
||||
* Add the named planes ZX YX ZY to define different normals (thanks @galou) #115
|
||||
* Code cleanup in accordance with PEP 8 (thanks @galou)
|
||||
* Fixed a bug with the close function not resetting the first point of the context correctly (thanks @huskier)
|
||||
* Fixed the findSolid function so that it handles compounds #107
|
||||
* Changed the polyline function so that it adds edges to the stack instead of a wire #102
|
||||
* Add the ability to find the center of the bounding box, rather than the center of mass (thanks @huskier) #122
|
||||
* Changed normalize function to normalized to match OCC/PythonOCC nomenclature #124
|
||||
* Added a label attribute to all freecad_impl.shapes so that they can have IDs attached to them #124
|
||||
* Added toFreecad() function as a convenience for val().wrapped
|
||||
* Converted all examples to use toFreecad()
|
||||
* Updated all version numbers that were missed before
|
||||
* Fixed import issues in Windows caused by fc_import
|
||||
* Added/fixed Mac OS support
|
||||
* Improved STEP import
|
||||
* Fixed bug in rotateAboutCenter that negated its effect on solids
|
||||
* Added Travis config (thanks @krasin)
|
||||
* Removed redundant workplane.py file left over from the PParts.com migration
|
||||
* Fixed toWorldCoordinates bug in moveTo (thanks @xix-xeaon)
|
||||
* Added new tests for 2D drawing functions
|
||||
* Integrated Coveralls.io, with a badge in README.md
|
||||
* Integrated version badge in README.md
|
||||
|
||||
v0.4.0
|
||||
------
|
||||
* Added Documentation, which is available on dcowden.github.io/cadquery
|
||||
* Added CQGI, an adapter API that standardizes use of cadquery from within structured execution environments
|
||||
* Added ability to import STEP files from a web URL (thanks @huskier ) #128
|
||||
|
||||
v0.4.1
|
||||
------
|
||||
* Minor CQGI updates
|
||||
|
||||
v0.5.0-stable
|
||||
------
|
||||
* Configuring Travis to push to PyPI on version releases.
|
||||
|
||||
v0.5.1
|
||||
------
|
||||
* Mirroring fixes (thanks @huskier)
|
||||
* Added a mirroring example (thanks @huskier)
|
||||
|
||||
v0.5.2
|
||||
------
|
||||
* Added the sweep operation #33
|
||||
|
||||
v1.0.0
|
||||
------
|
||||
* Added an option to do symmetric extrusion about the workplane (thanks @adam-urbanczyk)
|
||||
* Extended selector syntax to include Nth selector and re-implemented selectors using pyparsing (thanks @adam-urbanczyk)
|
||||
* Added logical operations to string selectors (thanks @adam-urbanczyk)
|
||||
* Cleanup of README.md and changes.md (thanks @baoboa)
|
||||
* Fixed bugs with toVector and Face 'Not Defined' errors (thanks @huskier)
|
||||
* Refactor of the initialization code for PEP8 compliance and Python 3 compatibility (thanks @Peque)
|
||||
* Making sure that the new pyparsing library dependency is handled properly (thanks @Peque)
|
||||
v0.1.7
|
||||
-----
|
||||
* Added revolve operation and supporting tests
|
||||
* Fixed minor documentation errors
|
||||
|
||||
v1.1.0 (Unreleased)
|
||||
------
|
||||
* Fixes and addition of graphical examples for selectors (thanks @adam-urbanczyk)
|
||||
* Added intersect operation (thanks @fragmuffin)
|
||||
v0.1.6
|
||||
-----
|
||||
* Added STEP import and supporting tests
|
||||
|
||||
v0.1
|
||||
-----
|
||||
* Initial Version
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
# if no output filename is provided, output goes to stdout
|
||||
# default output format is STEP
|
||||
#
|
||||
|
||||
from __future__ import print_function
|
||||
import sys,os
|
||||
|
||||
|
||||
|
@ -21,6 +21,7 @@ import os.path
|
|||
import json
|
||||
import tempfile
|
||||
|
||||
|
||||
class FilepathShapeWriter(object):
|
||||
#a shape writer that writes a new file in a directory for each object
|
||||
def __init__(self,file_pattern, shape_format):
|
||||
|
|
428
Libs/cadquery/doc/_static/box_export.step
vendored
Normal file
428
Libs/cadquery/doc/_static/box_export.step
vendored
Normal file
|
@ -0,0 +1,428 @@
|
|||
ISO-10303-21;
|
||||
HEADER;
|
||||
FILE_DESCRIPTION(('FreeCAD Model'),'2;1');
|
||||
FILE_NAME(
|
||||
'/home/jwright/Downloads/repos/cadquery-freecad-module/Libs/cadquery/doc
|
||||
/_static/example_step_export.step','2018-02-15T09:43:34',('Author'),('')
|
||||
,'Open CASCADE STEP processor 7.1','FreeCAD','Unknown');
|
||||
FILE_SCHEMA(('AUTOMOTIVE_DESIGN { 1 0 10303 214 1 1 1 1 }'));
|
||||
ENDSEC;
|
||||
DATA;
|
||||
#1 = APPLICATION_PROTOCOL_DEFINITION('international standard',
|
||||
'automotive_design',2000,#2);
|
||||
#2 = APPLICATION_CONTEXT(
|
||||
'core data for automotive mechanical design processes');
|
||||
#3 = SHAPE_DEFINITION_REPRESENTATION(#4,#10);
|
||||
#4 = PRODUCT_DEFINITION_SHAPE('','',#5);
|
||||
#5 = PRODUCT_DEFINITION('design','',#6,#9);
|
||||
#6 = PRODUCT_DEFINITION_FORMATION('','',#7);
|
||||
#7 = PRODUCT('Body','Body','',(#8));
|
||||
#8 = PRODUCT_CONTEXT('',#2,'mechanical');
|
||||
#9 = PRODUCT_DEFINITION_CONTEXT('part definition',#2,'design');
|
||||
#10 = ADVANCED_BREP_SHAPE_REPRESENTATION('',(#11,#15),#345);
|
||||
#11 = AXIS2_PLACEMENT_3D('',#12,#13,#14);
|
||||
#12 = CARTESIAN_POINT('',(0.,0.,0.));
|
||||
#13 = DIRECTION('',(0.,0.,1.));
|
||||
#14 = DIRECTION('',(1.,0.,-0.));
|
||||
#15 = MANIFOLD_SOLID_BREP('',#16);
|
||||
#16 = CLOSED_SHELL('',(#17,#137,#237,#284,#331,#338));
|
||||
#17 = ADVANCED_FACE('',(#18),#32,.F.);
|
||||
#18 = FACE_BOUND('',#19,.F.);
|
||||
#19 = EDGE_LOOP('',(#20,#55,#83,#111));
|
||||
#20 = ORIENTED_EDGE('',*,*,#21,.F.);
|
||||
#21 = EDGE_CURVE('',#22,#24,#26,.T.);
|
||||
#22 = VERTEX_POINT('',#23);
|
||||
#23 = CARTESIAN_POINT('',(0.,0.,0.));
|
||||
#24 = VERTEX_POINT('',#25);
|
||||
#25 = CARTESIAN_POINT('',(0.,0.,10.));
|
||||
#26 = SURFACE_CURVE('',#27,(#31,#43),.PCURVE_S1.);
|
||||
#27 = LINE('',#28,#29);
|
||||
#28 = CARTESIAN_POINT('',(0.,0.,0.));
|
||||
#29 = VECTOR('',#30,1.);
|
||||
#30 = DIRECTION('',(0.,0.,1.));
|
||||
#31 = PCURVE('',#32,#37);
|
||||
#32 = PLANE('',#33);
|
||||
#33 = AXIS2_PLACEMENT_3D('',#34,#35,#36);
|
||||
#34 = CARTESIAN_POINT('',(0.,0.,0.));
|
||||
#35 = DIRECTION('',(1.,0.,0.));
|
||||
#36 = DIRECTION('',(0.,0.,1.));
|
||||
#37 = DEFINITIONAL_REPRESENTATION('',(#38),#42);
|
||||
#38 = LINE('',#39,#40);
|
||||
#39 = CARTESIAN_POINT('',(0.,0.));
|
||||
#40 = VECTOR('',#41,1.);
|
||||
#41 = DIRECTION('',(1.,0.));
|
||||
#42 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2)
|
||||
PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
|
||||
) );
|
||||
#43 = PCURVE('',#44,#49);
|
||||
#44 = PLANE('',#45);
|
||||
#45 = AXIS2_PLACEMENT_3D('',#46,#47,#48);
|
||||
#46 = CARTESIAN_POINT('',(0.,0.,0.));
|
||||
#47 = DIRECTION('',(0.,1.,0.));
|
||||
#48 = DIRECTION('',(0.,0.,1.));
|
||||
#49 = DEFINITIONAL_REPRESENTATION('',(#50),#54);
|
||||
#50 = LINE('',#51,#52);
|
||||
#51 = CARTESIAN_POINT('',(0.,0.));
|
||||
#52 = VECTOR('',#53,1.);
|
||||
#53 = DIRECTION('',(1.,0.));
|
||||
#54 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2)
|
||||
PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
|
||||
) );
|
||||
#55 = ORIENTED_EDGE('',*,*,#56,.T.);
|
||||
#56 = EDGE_CURVE('',#22,#57,#59,.T.);
|
||||
#57 = VERTEX_POINT('',#58);
|
||||
#58 = CARTESIAN_POINT('',(0.,10.,0.));
|
||||
#59 = SURFACE_CURVE('',#60,(#64,#71),.PCURVE_S1.);
|
||||
#60 = LINE('',#61,#62);
|
||||
#61 = CARTESIAN_POINT('',(0.,0.,0.));
|
||||
#62 = VECTOR('',#63,1.);
|
||||
#63 = DIRECTION('',(0.,1.,0.));
|
||||
#64 = PCURVE('',#32,#65);
|
||||
#65 = DEFINITIONAL_REPRESENTATION('',(#66),#70);
|
||||
#66 = LINE('',#67,#68);
|
||||
#67 = CARTESIAN_POINT('',(0.,0.));
|
||||
#68 = VECTOR('',#69,1.);
|
||||
#69 = DIRECTION('',(0.,-1.));
|
||||
#70 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2)
|
||||
PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
|
||||
) );
|
||||
#71 = PCURVE('',#72,#77);
|
||||
#72 = PLANE('',#73);
|
||||
#73 = AXIS2_PLACEMENT_3D('',#74,#75,#76);
|
||||
#74 = CARTESIAN_POINT('',(0.,0.,0.));
|
||||
#75 = DIRECTION('',(0.,0.,1.));
|
||||
#76 = DIRECTION('',(1.,0.,0.));
|
||||
#77 = DEFINITIONAL_REPRESENTATION('',(#78),#82);
|
||||
#78 = LINE('',#79,#80);
|
||||
#79 = CARTESIAN_POINT('',(0.,0.));
|
||||
#80 = VECTOR('',#81,1.);
|
||||
#81 = DIRECTION('',(0.,1.));
|
||||
#82 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2)
|
||||
PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
|
||||
) );
|
||||
#83 = ORIENTED_EDGE('',*,*,#84,.T.);
|
||||
#84 = EDGE_CURVE('',#57,#85,#87,.T.);
|
||||
#85 = VERTEX_POINT('',#86);
|
||||
#86 = CARTESIAN_POINT('',(0.,10.,10.));
|
||||
#87 = SURFACE_CURVE('',#88,(#92,#99),.PCURVE_S1.);
|
||||
#88 = LINE('',#89,#90);
|
||||
#89 = CARTESIAN_POINT('',(0.,10.,0.));
|
||||
#90 = VECTOR('',#91,1.);
|
||||
#91 = DIRECTION('',(0.,0.,1.));
|
||||
#92 = PCURVE('',#32,#93);
|
||||
#93 = DEFINITIONAL_REPRESENTATION('',(#94),#98);
|
||||
#94 = LINE('',#95,#96);
|
||||
#95 = CARTESIAN_POINT('',(0.,-10.));
|
||||
#96 = VECTOR('',#97,1.);
|
||||
#97 = DIRECTION('',(1.,0.));
|
||||
#98 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2)
|
||||
PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
|
||||
) );
|
||||
#99 = PCURVE('',#100,#105);
|
||||
#100 = PLANE('',#101);
|
||||
#101 = AXIS2_PLACEMENT_3D('',#102,#103,#104);
|
||||
#102 = CARTESIAN_POINT('',(0.,10.,0.));
|
||||
#103 = DIRECTION('',(0.,1.,0.));
|
||||
#104 = DIRECTION('',(0.,0.,1.));
|
||||
#105 = DEFINITIONAL_REPRESENTATION('',(#106),#110);
|
||||
#106 = LINE('',#107,#108);
|
||||
#107 = CARTESIAN_POINT('',(0.,0.));
|
||||
#108 = VECTOR('',#109,1.);
|
||||
#109 = DIRECTION('',(1.,0.));
|
||||
#110 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2)
|
||||
PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
|
||||
) );
|
||||
#111 = ORIENTED_EDGE('',*,*,#112,.F.);
|
||||
#112 = EDGE_CURVE('',#24,#85,#113,.T.);
|
||||
#113 = SURFACE_CURVE('',#114,(#118,#125),.PCURVE_S1.);
|
||||
#114 = LINE('',#115,#116);
|
||||
#115 = CARTESIAN_POINT('',(0.,0.,10.));
|
||||
#116 = VECTOR('',#117,1.);
|
||||
#117 = DIRECTION('',(0.,1.,0.));
|
||||
#118 = PCURVE('',#32,#119);
|
||||
#119 = DEFINITIONAL_REPRESENTATION('',(#120),#124);
|
||||
#120 = LINE('',#121,#122);
|
||||
#121 = CARTESIAN_POINT('',(10.,0.));
|
||||
#122 = VECTOR('',#123,1.);
|
||||
#123 = DIRECTION('',(0.,-1.));
|
||||
#124 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2)
|
||||
PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
|
||||
) );
|
||||
#125 = PCURVE('',#126,#131);
|
||||
#126 = PLANE('',#127);
|
||||
#127 = AXIS2_PLACEMENT_3D('',#128,#129,#130);
|
||||
#128 = CARTESIAN_POINT('',(0.,0.,10.));
|
||||
#129 = DIRECTION('',(0.,0.,1.));
|
||||
#130 = DIRECTION('',(1.,0.,0.));
|
||||
#131 = DEFINITIONAL_REPRESENTATION('',(#132),#136);
|
||||
#132 = LINE('',#133,#134);
|
||||
#133 = CARTESIAN_POINT('',(0.,0.));
|
||||
#134 = VECTOR('',#135,1.);
|
||||
#135 = DIRECTION('',(0.,1.));
|
||||
#136 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2)
|
||||
PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
|
||||
) );
|
||||
#137 = ADVANCED_FACE('',(#138),#152,.T.);
|
||||
#138 = FACE_BOUND('',#139,.T.);
|
||||
#139 = EDGE_LOOP('',(#140,#170,#193,#216));
|
||||
#140 = ORIENTED_EDGE('',*,*,#141,.F.);
|
||||
#141 = EDGE_CURVE('',#142,#144,#146,.T.);
|
||||
#142 = VERTEX_POINT('',#143);
|
||||
#143 = CARTESIAN_POINT('',(10.,0.,0.));
|
||||
#144 = VERTEX_POINT('',#145);
|
||||
#145 = CARTESIAN_POINT('',(10.,0.,10.));
|
||||
#146 = SURFACE_CURVE('',#147,(#151,#163),.PCURVE_S1.);
|
||||
#147 = LINE('',#148,#149);
|
||||
#148 = CARTESIAN_POINT('',(10.,0.,0.));
|
||||
#149 = VECTOR('',#150,1.);
|
||||
#150 = DIRECTION('',(0.,0.,1.));
|
||||
#151 = PCURVE('',#152,#157);
|
||||
#152 = PLANE('',#153);
|
||||
#153 = AXIS2_PLACEMENT_3D('',#154,#155,#156);
|
||||
#154 = CARTESIAN_POINT('',(10.,0.,0.));
|
||||
#155 = DIRECTION('',(1.,0.,0.));
|
||||
#156 = DIRECTION('',(0.,0.,1.));
|
||||
#157 = DEFINITIONAL_REPRESENTATION('',(#158),#162);
|
||||
#158 = LINE('',#159,#160);
|
||||
#159 = CARTESIAN_POINT('',(0.,0.));
|
||||
#160 = VECTOR('',#161,1.);
|
||||
#161 = DIRECTION('',(1.,0.));
|
||||
#162 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2)
|
||||
PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
|
||||
) );
|
||||
#163 = PCURVE('',#44,#164);
|
||||
#164 = DEFINITIONAL_REPRESENTATION('',(#165),#169);
|
||||
#165 = LINE('',#166,#167);
|
||||
#166 = CARTESIAN_POINT('',(0.,10.));
|
||||
#167 = VECTOR('',#168,1.);
|
||||
#168 = DIRECTION('',(1.,0.));
|
||||
#169 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2)
|
||||
PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
|
||||
) );
|
||||
#170 = ORIENTED_EDGE('',*,*,#171,.T.);
|
||||
#171 = EDGE_CURVE('',#142,#172,#174,.T.);
|
||||
#172 = VERTEX_POINT('',#173);
|
||||
#173 = CARTESIAN_POINT('',(10.,10.,0.));
|
||||
#174 = SURFACE_CURVE('',#175,(#179,#186),.PCURVE_S1.);
|
||||
#175 = LINE('',#176,#177);
|
||||
#176 = CARTESIAN_POINT('',(10.,0.,0.));
|
||||
#177 = VECTOR('',#178,1.);
|
||||
#178 = DIRECTION('',(0.,1.,0.));
|
||||
#179 = PCURVE('',#152,#180);
|
||||
#180 = DEFINITIONAL_REPRESENTATION('',(#181),#185);
|
||||
#181 = LINE('',#182,#183);
|
||||
#182 = CARTESIAN_POINT('',(0.,0.));
|
||||
#183 = VECTOR('',#184,1.);
|
||||
#184 = DIRECTION('',(0.,-1.));
|
||||
#185 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2)
|
||||
PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
|
||||
) );
|
||||
#186 = PCURVE('',#72,#187);
|
||||
#187 = DEFINITIONAL_REPRESENTATION('',(#188),#192);
|
||||
#188 = LINE('',#189,#190);
|
||||
#189 = CARTESIAN_POINT('',(10.,0.));
|
||||
#190 = VECTOR('',#191,1.);
|
||||
#191 = DIRECTION('',(0.,1.));
|
||||
#192 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2)
|
||||
PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
|
||||
) );
|
||||
#193 = ORIENTED_EDGE('',*,*,#194,.T.);
|
||||
#194 = EDGE_CURVE('',#172,#195,#197,.T.);
|
||||
#195 = VERTEX_POINT('',#196);
|
||||
#196 = CARTESIAN_POINT('',(10.,10.,10.));
|
||||
#197 = SURFACE_CURVE('',#198,(#202,#209),.PCURVE_S1.);
|
||||
#198 = LINE('',#199,#200);
|
||||
#199 = CARTESIAN_POINT('',(10.,10.,0.));
|
||||
#200 = VECTOR('',#201,1.);
|
||||
#201 = DIRECTION('',(0.,0.,1.));
|
||||
#202 = PCURVE('',#152,#203);
|
||||
#203 = DEFINITIONAL_REPRESENTATION('',(#204),#208);
|
||||
#204 = LINE('',#205,#206);
|
||||
#205 = CARTESIAN_POINT('',(0.,-10.));
|
||||
#206 = VECTOR('',#207,1.);
|
||||
#207 = DIRECTION('',(1.,0.));
|
||||
#208 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2)
|
||||
PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
|
||||
) );
|
||||
#209 = PCURVE('',#100,#210);
|
||||
#210 = DEFINITIONAL_REPRESENTATION('',(#211),#215);
|
||||
#211 = LINE('',#212,#213);
|
||||
#212 = CARTESIAN_POINT('',(0.,10.));
|
||||
#213 = VECTOR('',#214,1.);
|
||||
#214 = DIRECTION('',(1.,0.));
|
||||
#215 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2)
|
||||
PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
|
||||
) );
|
||||
#216 = ORIENTED_EDGE('',*,*,#217,.F.);
|
||||
#217 = EDGE_CURVE('',#144,#195,#218,.T.);
|
||||
#218 = SURFACE_CURVE('',#219,(#223,#230),.PCURVE_S1.);
|
||||
#219 = LINE('',#220,#221);
|
||||
#220 = CARTESIAN_POINT('',(10.,0.,10.));
|
||||
#221 = VECTOR('',#222,1.);
|
||||
#222 = DIRECTION('',(0.,1.,0.));
|
||||
#223 = PCURVE('',#152,#224);
|
||||
#224 = DEFINITIONAL_REPRESENTATION('',(#225),#229);
|
||||
#225 = LINE('',#226,#227);
|
||||
#226 = CARTESIAN_POINT('',(10.,0.));
|
||||
#227 = VECTOR('',#228,1.);
|
||||
#228 = DIRECTION('',(0.,-1.));
|
||||
#229 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2)
|
||||
PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
|
||||
) );
|
||||
#230 = PCURVE('',#126,#231);
|
||||
#231 = DEFINITIONAL_REPRESENTATION('',(#232),#236);
|
||||
#232 = LINE('',#233,#234);
|
||||
#233 = CARTESIAN_POINT('',(10.,0.));
|
||||
#234 = VECTOR('',#235,1.);
|
||||
#235 = DIRECTION('',(0.,1.));
|
||||
#236 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2)
|
||||
PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
|
||||
) );
|
||||
#237 = ADVANCED_FACE('',(#238),#44,.F.);
|
||||
#238 = FACE_BOUND('',#239,.F.);
|
||||
#239 = EDGE_LOOP('',(#240,#261,#262,#283));
|
||||
#240 = ORIENTED_EDGE('',*,*,#241,.F.);
|
||||
#241 = EDGE_CURVE('',#22,#142,#242,.T.);
|
||||
#242 = SURFACE_CURVE('',#243,(#247,#254),.PCURVE_S1.);
|
||||
#243 = LINE('',#244,#245);
|
||||
#244 = CARTESIAN_POINT('',(0.,0.,0.));
|
||||
#245 = VECTOR('',#246,1.);
|
||||
#246 = DIRECTION('',(1.,0.,0.));
|
||||
#247 = PCURVE('',#44,#248);
|
||||
#248 = DEFINITIONAL_REPRESENTATION('',(#249),#253);
|
||||
#249 = LINE('',#250,#251);
|
||||
#250 = CARTESIAN_POINT('',(0.,0.));
|
||||
#251 = VECTOR('',#252,1.);
|
||||
#252 = DIRECTION('',(0.,1.));
|
||||
#253 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2)
|
||||
PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
|
||||
) );
|
||||
#254 = PCURVE('',#72,#255);
|
||||
#255 = DEFINITIONAL_REPRESENTATION('',(#256),#260);
|
||||
#256 = LINE('',#257,#258);
|
||||
#257 = CARTESIAN_POINT('',(0.,0.));
|
||||
#258 = VECTOR('',#259,1.);
|
||||
#259 = DIRECTION('',(1.,0.));
|
||||
#260 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2)
|
||||
PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
|
||||
) );
|
||||
#261 = ORIENTED_EDGE('',*,*,#21,.T.);
|
||||
#262 = ORIENTED_EDGE('',*,*,#263,.T.);
|
||||
#263 = EDGE_CURVE('',#24,#144,#264,.T.);
|
||||
#264 = SURFACE_CURVE('',#265,(#269,#276),.PCURVE_S1.);
|
||||
#265 = LINE('',#266,#267);
|
||||
#266 = CARTESIAN_POINT('',(0.,0.,10.));
|
||||
#267 = VECTOR('',#268,1.);
|
||||
#268 = DIRECTION('',(1.,0.,0.));
|
||||
#269 = PCURVE('',#44,#270);
|
||||
#270 = DEFINITIONAL_REPRESENTATION('',(#271),#275);
|
||||
#271 = LINE('',#272,#273);
|
||||
#272 = CARTESIAN_POINT('',(10.,0.));
|
||||
#273 = VECTOR('',#274,1.);
|
||||
#274 = DIRECTION('',(0.,1.));
|
||||
#275 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2)
|
||||
PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
|
||||
) );
|
||||
#276 = PCURVE('',#126,#277);
|
||||
#277 = DEFINITIONAL_REPRESENTATION('',(#278),#282);
|
||||
#278 = LINE('',#279,#280);
|
||||
#279 = CARTESIAN_POINT('',(0.,0.));
|
||||
#280 = VECTOR('',#281,1.);
|
||||
#281 = DIRECTION('',(1.,0.));
|
||||
#282 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2)
|
||||
PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
|
||||
) );
|
||||
#283 = ORIENTED_EDGE('',*,*,#141,.F.);
|
||||
#284 = ADVANCED_FACE('',(#285),#100,.T.);
|
||||
#285 = FACE_BOUND('',#286,.T.);
|
||||
#286 = EDGE_LOOP('',(#287,#308,#309,#330));
|
||||
#287 = ORIENTED_EDGE('',*,*,#288,.F.);
|
||||
#288 = EDGE_CURVE('',#57,#172,#289,.T.);
|
||||
#289 = SURFACE_CURVE('',#290,(#294,#301),.PCURVE_S1.);
|
||||
#290 = LINE('',#291,#292);
|
||||
#291 = CARTESIAN_POINT('',(0.,10.,0.));
|
||||
#292 = VECTOR('',#293,1.);
|
||||
#293 = DIRECTION('',(1.,0.,0.));
|
||||
#294 = PCURVE('',#100,#295);
|
||||
#295 = DEFINITIONAL_REPRESENTATION('',(#296),#300);
|
||||
#296 = LINE('',#297,#298);
|
||||
#297 = CARTESIAN_POINT('',(0.,0.));
|
||||
#298 = VECTOR('',#299,1.);
|
||||
#299 = DIRECTION('',(0.,1.));
|
||||
#300 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2)
|
||||
PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
|
||||
) );
|
||||
#301 = PCURVE('',#72,#302);
|
||||
#302 = DEFINITIONAL_REPRESENTATION('',(#303),#307);
|
||||
#303 = LINE('',#304,#305);
|
||||
#304 = CARTESIAN_POINT('',(0.,10.));
|
||||
#305 = VECTOR('',#306,1.);
|
||||
#306 = DIRECTION('',(1.,0.));
|
||||
#307 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2)
|
||||
PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
|
||||
) );
|
||||
#308 = ORIENTED_EDGE('',*,*,#84,.T.);
|
||||
#309 = ORIENTED_EDGE('',*,*,#310,.T.);
|
||||
#310 = EDGE_CURVE('',#85,#195,#311,.T.);
|
||||
#311 = SURFACE_CURVE('',#312,(#316,#323),.PCURVE_S1.);
|
||||
#312 = LINE('',#313,#314);
|
||||
#313 = CARTESIAN_POINT('',(0.,10.,10.));
|
||||
#314 = VECTOR('',#315,1.);
|
||||
#315 = DIRECTION('',(1.,0.,0.));
|
||||
#316 = PCURVE('',#100,#317);
|
||||
#317 = DEFINITIONAL_REPRESENTATION('',(#318),#322);
|
||||
#318 = LINE('',#319,#320);
|
||||
#319 = CARTESIAN_POINT('',(10.,0.));
|
||||
#320 = VECTOR('',#321,1.);
|
||||
#321 = DIRECTION('',(0.,1.));
|
||||
#322 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2)
|
||||
PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
|
||||
) );
|
||||
#323 = PCURVE('',#126,#324);
|
||||
#324 = DEFINITIONAL_REPRESENTATION('',(#325),#329);
|
||||
#325 = LINE('',#326,#327);
|
||||
#326 = CARTESIAN_POINT('',(0.,10.));
|
||||
#327 = VECTOR('',#328,1.);
|
||||
#328 = DIRECTION('',(1.,0.));
|
||||
#329 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2)
|
||||
PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
|
||||
) );
|
||||
#330 = ORIENTED_EDGE('',*,*,#194,.F.);
|
||||
#331 = ADVANCED_FACE('',(#332),#72,.F.);
|
||||
#332 = FACE_BOUND('',#333,.F.);
|
||||
#333 = EDGE_LOOP('',(#334,#335,#336,#337));
|
||||
#334 = ORIENTED_EDGE('',*,*,#56,.F.);
|
||||
#335 = ORIENTED_EDGE('',*,*,#241,.T.);
|
||||
#336 = ORIENTED_EDGE('',*,*,#171,.T.);
|
||||
#337 = ORIENTED_EDGE('',*,*,#288,.F.);
|
||||
#338 = ADVANCED_FACE('',(#339),#126,.T.);
|
||||
#339 = FACE_BOUND('',#340,.T.);
|
||||
#340 = EDGE_LOOP('',(#341,#342,#343,#344));
|
||||
#341 = ORIENTED_EDGE('',*,*,#112,.F.);
|
||||
#342 = ORIENTED_EDGE('',*,*,#263,.T.);
|
||||
#343 = ORIENTED_EDGE('',*,*,#217,.T.);
|
||||
#344 = ORIENTED_EDGE('',*,*,#310,.F.);
|
||||
#345 = ( GEOMETRIC_REPRESENTATION_CONTEXT(3)
|
||||
GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT((#349)) GLOBAL_UNIT_ASSIGNED_CONTEXT
|
||||
((#346,#347,#348)) REPRESENTATION_CONTEXT('Context #1',
|
||||
'3D Context with UNIT and UNCERTAINTY') );
|
||||
#346 = ( LENGTH_UNIT() NAMED_UNIT(*) SI_UNIT(.MILLI.,.METRE.) );
|
||||
#347 = ( NAMED_UNIT(*) PLANE_ANGLE_UNIT() SI_UNIT($,.RADIAN.) );
|
||||
#348 = ( NAMED_UNIT(*) SI_UNIT($,.STERADIAN.) SOLID_ANGLE_UNIT() );
|
||||
#349 = UNCERTAINTY_MEASURE_WITH_UNIT(LENGTH_MEASURE(1.E-07),#346,
|
||||
'distance_accuracy_value','confusion accuracy');
|
||||
#350 = PRODUCT_RELATED_PRODUCT_CATEGORY('part',$,(#7));
|
||||
#351 = MECHANICAL_DESIGN_GEOMETRIC_PRESENTATION_REPRESENTATION('',(#352)
|
||||
,#345);
|
||||
#352 = STYLED_ITEM('color',(#353),#15);
|
||||
#353 = PRESENTATION_STYLE_ASSIGNMENT((#354,#360));
|
||||
#354 = SURFACE_STYLE_USAGE(.BOTH.,#355);
|
||||
#355 = SURFACE_SIDE_STYLE('',(#356));
|
||||
#356 = SURFACE_STYLE_FILL_AREA(#357);
|
||||
#357 = FILL_AREA_STYLE('',(#358));
|
||||
#358 = FILL_AREA_STYLE_COLOUR('',#359);
|
||||
#359 = COLOUR_RGB('',0.800000011921,0.800000011921,0.800000011921);
|
||||
#360 = CURVE_STYLE('',#361,POSITIVE_LENGTH_MEASURE(0.1),#359);
|
||||
#361 = DRAUGHTING_PRE_DEFINED_CURVE_FONT('continuous');
|
||||
ENDSEC;
|
||||
END-ISO-10303-21;
|
|
@ -144,7 +144,7 @@ html_title = "CadQuery Documentation"
|
|||
|
||||
# The name of an image file (relative to this directory) to place at the top
|
||||
# of the sidebar.
|
||||
html_logo = "_static/cqlogo.png"
|
||||
html_logo = "_static/logo/cadquery_logo_dark.svg"
|
||||
|
||||
# The name of an image file (within the static path) to use as favicon of the
|
||||
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
The CadQuery Gateway Interface
|
||||
====================================
|
||||
|
||||
|
||||
CadQuery is first and foremost designed as a library, which can be used as a part of any project.
|
||||
In this context, there is no need for a standard script format or gateway api.
|
||||
|
||||
|
@ -19,12 +18,10 @@ Today, three execution environments exist:
|
|||
inside of the FreeCAD IDE, and displays objects in the display window
|
||||
* the cq-directive, which is used to execute scripts inside of sphinx-doc,
|
||||
producing documented examples that include both a script and an SVG representation of the object that results
|
||||
* `ParametricParts.com <https://www.parametricparts.com>`_, which provides a web-based way to prompt user input for
|
||||
variables, and then display the result output in a web page.
|
||||
* `Jupyter Notebooks <https://mybinder.org/v2/gh/RustyVermeer/tryCQ/master>`_, which provide a web-based way to build, view, and export scripts.
|
||||
|
||||
The CQGI is distributed with cadquery, and standardizes the interface between execution environments and cadquery scripts.
|
||||
|
||||
|
||||
The Script Side
|
||||
-----------------
|
||||
|
||||
|
|
|
@ -9,9 +9,9 @@ If you are using cadquery as a library, there are no constraints.
|
|||
|
||||
If you are using cadquery scripts inside of a cadquery execution environment,
|
||||
like `The CadQuery Freecad Module <https://github.com/jmwright/cadquery-freecad-module>`_ or
|
||||
`parametricParts.com <https://www.parametricparts.com>`_, there are a few conventions you need to be aware of:
|
||||
`Jupyter notebooks <https://mybinder.org/v2/gh/RustyVermeer/tryCQ/master>`_, there are a few conventions you need to be aware of:
|
||||
|
||||
* cadquery is already imported as 'cq'
|
||||
* cadquery is imported as 'cq'
|
||||
* to return an object to the container, you need to call the show_object() method.
|
||||
|
||||
Each script generally has three sections:
|
||||
|
|
|
@ -47,12 +47,8 @@ If you prefer to have a GUI available, your best option is to use
|
|||
Simply extract cadquery-freecad-module into your FreeCAD installation. You'll end up
|
||||
with a cadquery workbench that allows you to interactively run scripts, and then see the results in the FreeCAD GUI
|
||||
|
||||
Zero Step Install
|
||||
Zero Step Install
|
||||
-------------------------------------------------
|
||||
|
||||
If you would like to use cadquery with no installation all, you can
|
||||
use `ParametricParts.com <https://www.parametricparts.com>`_, a web-based platform that runs cadquery scripts
|
||||
|
||||
It is free, and allows running and viewing cadquery scripts in your web browser or mobile phone
|
||||
|
||||
|
||||
use mybinder to `launch a Jupyter Notebook Server <https://mybinder.org/v2/gh/RustyVermeer/tryCQ/master>`_ pre-configured to run CadQuery.
|
|
@ -31,7 +31,7 @@ produces a flat plate with a hole in the middle::
|
|||
|
||||
.. image:: _static/simpleblock.png
|
||||
|
||||
That's a bit of a dixie-cup example. But it is pretty similar to a more useful part: a parametric pillow block for a
|
||||
That is a simple example, but it is similar to a more useful part: a parametric pillow block for a
|
||||
standard 608-size ball bearing::
|
||||
|
||||
(length,height,diam, thickness,padding) = ( 30.0,40.0,22.0,10.0,8.0)
|
||||
|
@ -43,7 +43,7 @@ standard 608-size ball bearing::
|
|||
|
||||
.. image:: _static/pillowblock.png
|
||||
|
||||
Lots more examples are available in the :ref:`examples`
|
||||
Many examples are available in the :ref:`examples`
|
||||
|
||||
CadQuery is a library, GUIs are separate
|
||||
==============================================
|
||||
|
@ -51,16 +51,16 @@ CadQuery is a library, GUIs are separate
|
|||
CadQuery is a library, that's intentionally designed to be usable as a GUI-less library. This enables
|
||||
its use in a variety of engineering and scientific applications that create 3d models programmatically.
|
||||
|
||||
If you'd like a GUI, you have a couple of options:
|
||||
If you would like a GUI, you have a couple of options:
|
||||
|
||||
* Install cadquery as a part of `The CadQuery Freecad Module <https://github.com/jmwright/cadquery-freecad-module>`_
|
||||
* Use `ParametricParts.com <https://www.parametricparts.com>`_, a web-based platform that runs cadQuery scripts
|
||||
* Use `tryCQ <https://mybinder.org/v2/gh/RustyVermeer/tryCQ/master>`_, a Jupyter Notebook server using `mybinder.org <https://mybinder.org/>`_. This solution runs entirely in your browser.
|
||||
|
||||
|
||||
Why CadQuery instead of OpenSCAD?
|
||||
============================================
|
||||
|
||||
Like OpenSCAD, CadQuery is an open-source, script based, parametric model generator. But CadQuery has several key advantages:
|
||||
Like OpenSCAD, CadQuery is an open-source, script based, parametric model generator. However, CadQuery stands out in many ways and has several key advantages:
|
||||
|
||||
1. **The scripts use a standard programming language**, python, and thus can benefit from the associated infrastructure.
|
||||
This includes many standard libraries and IDEs
|
||||
|
@ -69,7 +69,7 @@ Like OpenSCAD, CadQuery is an open-source, script based, parametric model genera
|
|||
by OCC include NURBS, splines, surface sewing, STL repair, STEP import/export, and other complex operations,
|
||||
in addition to the standard CSG operations supported by CGAL
|
||||
|
||||
3. **Ability to import/export STEP** We think the ability to begin with a STEP model, created in a CAD package,
|
||||
3. **Ability to import/export STEP** the ability to begin with a STEP model, created in a CAD package,
|
||||
and then add parametric features is key. This is possible in OpenSCAD using STL, but STL is a lossy format
|
||||
|
||||
4. **Less Code and easier scripting** CadQuery scripts require less code to create most objects, because it is possible to locate
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
|
||||
from __future__ import division
|
||||
|
||||
from collections import namedtuple
|
||||
|
||||
import cadquery as cq
|
||||
|
||||
# text_lines is a list of text lines.
|
||||
# FreeCAD in braille (converted with braille-converter:
|
||||
# "CadQuery" in braille (converted with braille-converter:
|
||||
# https://github.com/jpaugh/braille-converter.git).
|
||||
text_lines = ['⠠ ⠋ ⠗ ⠑ ⠑ ⠠ ⠉ ⠠ ⠁ ⠠ ⠙']
|
||||
text_lines = [u'⠠ ⠉ ⠁ ⠙ ⠠ ⠟ ⠥ ⠻ ⠽']
|
||||
# See http://www.tiresias.org/research/reports/braille_cell.htm for examples
|
||||
# of braille cell geometry.
|
||||
horizontal_interdot = 2.5
|
||||
|
@ -40,16 +40,18 @@ class Point(object):
|
|||
return Point(self.x + other.x, self.y + other.y)
|
||||
|
||||
def __len__(self):
|
||||
"""Necessary to have it accepted as input to CadQuery"""
|
||||
return 2
|
||||
|
||||
def __getitem__(self, index):
|
||||
"""Necessary to have it accepted as input to CadQuery"""
|
||||
return (self.x, self.y)[index]
|
||||
|
||||
def __str__(self):
|
||||
return '({}, {})'.format(self.x, self.y)
|
||||
|
||||
|
||||
def brailleToPoints(text, cell_geometry):
|
||||
def braille_to_points(text, cell_geometry):
|
||||
# Unicode bit pattern (cf. https://en.wikipedia.org/wiki/Braille_Patterns).
|
||||
mask1 = 0b00000001
|
||||
mask2 = 0b00000010
|
||||
|
@ -75,7 +77,7 @@ def brailleToPoints(text, cell_geometry):
|
|||
pos = (pos1, pos2, pos3, pos4, pos5, pos6, pos7, pos8)
|
||||
|
||||
# Braille blank pattern (u'\u2800').
|
||||
blank = '⠀'
|
||||
blank = u'⠀'
|
||||
points = []
|
||||
# Position of dot1 along the x-axis (horizontal).
|
||||
character_origin = 0
|
||||
|
@ -108,8 +110,8 @@ def get_plate_width(text_lines, cell_geometry):
|
|||
def get_cylinder_radius(cell_geometry):
|
||||
"""Return the radius the cylinder should have
|
||||
|
||||
The cylinder have the same radius as the half-sphere make the dots (the
|
||||
hidden and the shown part of the dots).
|
||||
The cylinder have the same radius as the half-sphere that make the dots
|
||||
(the hidden and the shown part of the dots).
|
||||
The radius is such that the spherical cap with diameter
|
||||
cell_geometry.dot_diameter has a height of cell_geometry.dot_height.
|
||||
"""
|
||||
|
@ -138,7 +140,7 @@ def make_embossed_plate(text_lines, cell_geometry):
|
|||
"""Make an embossed plate with dots as spherical caps
|
||||
|
||||
Method:
|
||||
- make a thin plate on which sit cylinders
|
||||
- make a thin plate, called base, on which sit cylinders
|
||||
- fillet the upper edge of the cylinders so to get pseudo half-spheres
|
||||
- make the union with a thicker plate so that only the sphere caps stay
|
||||
"visible".
|
||||
|
@ -151,7 +153,7 @@ def make_embossed_plate(text_lines, cell_geometry):
|
|||
y = base_height - 3 * cell_geometry.vertical_interdot
|
||||
line_start_pos = Point(cell_geometry.horizontal_interdot, y)
|
||||
for text in text_lines:
|
||||
dots = brailleToPoints(text, cell_geometry)
|
||||
dots = braille_to_points(text, cell_geometry)
|
||||
dots = [p + line_start_pos for p in dots]
|
||||
dot_pos += dots
|
||||
line_start_pos += Point(0, -cell_geometry.interline)
|
||||
|
|
|
@ -4,7 +4,8 @@ from tests import *
|
|||
import cadquery
|
||||
import unittest
|
||||
|
||||
#if you are on python 2.7, you can use -m uniitest discover.
|
||||
#if you are on python 2.7, you can use.
|
||||
# python -m unittest discover -s tests -p "Test*" --verbose
|
||||
#but this is required for python 2.6.6 on windows. FreeCAD0.12 will not load
|
||||
#on py 2.7.x on win
|
||||
suite = unittest.TestSuite()
|
||||
|
@ -17,4 +18,7 @@ suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TestCadQuery.TestCadQ
|
|||
suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TestExporters.TestExporters))
|
||||
suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TestImporters.TestImporters))
|
||||
suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TestLogging.TestLogging))
|
||||
unittest.TextTestRunner().run(suite)
|
||||
|
||||
if __name__ == '__main__':
|
||||
result = unittest.TextTestRunner().run(suite)
|
||||
sys.exit(not result.wasSuccessful())
|
||||
|
|
|
@ -102,7 +102,7 @@ class TestCQGI(BaseTest):
|
|||
result = model.build({})
|
||||
self.assertFalse(result.success)
|
||||
self.assertIsNotNone(result.exception)
|
||||
self.assertTrue(result.exception.message == "ERROR")
|
||||
self.assertTrue(result.exception.args[0] == "ERROR")
|
||||
|
||||
def test_that_invalid_syntax_in_script_fails_immediately(self):
|
||||
badscript = textwrap.dedent(
|
||||
|
@ -114,7 +114,7 @@ class TestCQGI(BaseTest):
|
|||
with self.assertRaises(Exception) as context:
|
||||
model = cqgi.CQModel(badscript)
|
||||
|
||||
self.assertTrue('invalid syntax' in context.exception)
|
||||
self.assertTrue('invalid syntax' in context.exception.args)
|
||||
|
||||
def test_that_two_results_are_returned(self):
|
||||
script = textwrap.dedent(
|
||||
|
|
|
@ -1,32 +1,143 @@
|
|||
#system modules
|
||||
from __future__ import division
|
||||
import sys
|
||||
import unittest
|
||||
from math import pi, sin, sqrt, radians
|
||||
from tests import BaseTest
|
||||
import FreeCAD
|
||||
import Part
|
||||
|
||||
from copy import copy
|
||||
|
||||
from cadquery import *
|
||||
|
||||
class TestCadObjects(BaseTest):
|
||||
|
||||
def testVectorConstructors(self):
|
||||
v1 = Vector(1, 2, 3)
|
||||
v2 = Vector((1, 2, 3))
|
||||
v3 = Vector(FreeCAD.Base.Vector(1, 2, 3))
|
||||
# Assert 3 ints represents x, y, z respectively
|
||||
# (why?, this is assumed for all other assertions)
|
||||
v = Vector(1, 2, 3)
|
||||
self.assertEqual((v.x, v.y, v.z), (1, 2, 3))
|
||||
|
||||
for v in [v1, v2, v3]:
|
||||
self.assertTupleAlmostEquals((1, 2, 3), v.toTuple(), 4)
|
||||
# --- Positive Cases
|
||||
# empty
|
||||
self.assertEquals(Vector(), Vector(0, 0, 0))
|
||||
# tuples
|
||||
self.assertEquals(Vector((1, 2, 3)), Vector(1, 2, 3))
|
||||
self.assertEquals(Vector((1, 2)), Vector(1, 2, 0))
|
||||
self.assertEquals(Vector((1,)), Vector(1, 0, 0))
|
||||
# lists
|
||||
self.assertEquals(Vector([1, 2, 3]), Vector(1, 2, 3))
|
||||
self.assertEquals(Vector([1, 2]), Vector(1, 2, 0))
|
||||
self.assertEquals(Vector([1]), Vector(1, 0, 0))
|
||||
# < 3 numbers
|
||||
self.assertEquals(Vector(1, 2), Vector(1, 2, 0))
|
||||
self.assertEquals(Vector(1), Vector(1, 0, 0))
|
||||
# wrappers
|
||||
self.assertEquals(Vector(Vector(1, 2, 3)), Vector(1, 2, 3))
|
||||
self.assertEquals(Vector(FreeCAD.Base.Vector(1, 2, 3)), Vector(1, 2, 3))
|
||||
# named coords
|
||||
self.assertEquals(Vector(x=1, y=2, z=3), Vector(1, 2, 3))
|
||||
self.assertEquals(Vector(x=1), Vector(1, 0, 0))
|
||||
self.assertEquals(Vector(y=2), Vector(0, 2, 0))
|
||||
self.assertEquals(Vector(z=3), Vector(0, 0, 3))
|
||||
|
||||
# --- Negative Cases
|
||||
with self.assertRaises(ValueError):
|
||||
Vector('blah') # invalid type
|
||||
with self.assertRaises(ValueError):
|
||||
Vector(1, 2, 3, 4)
|
||||
with self.assertRaises(ValueError):
|
||||
Vector((1, 2, 3, 4))
|
||||
with self.assertRaises(ValueError):
|
||||
Vector([1, 2, 3, 4])
|
||||
with self.assertRaises(ValueError):
|
||||
# mixing listed and named args not supported
|
||||
Vector(1, 2, z=3)
|
||||
with self.assertRaises(ValueError):
|
||||
# non-numeric as first parameter
|
||||
Vector(FreeCAD.Base.Vector(1, 2, 3), 1)
|
||||
|
||||
def testVectorCopy(self):
|
||||
a = Vector(1, 2, 3)
|
||||
b = copy(a)
|
||||
# assert copy is equal
|
||||
self.assertEqual(a.toTuple(), (1, 2, 3))
|
||||
self.assertEqual(b.toTuple(), (1, 2, 3))
|
||||
# assert changes to original don't effect copy
|
||||
a.x = 100
|
||||
self.assertEqual(a.toTuple(), (100, 2, 3))
|
||||
self.assertEqual(b.toTuple(), (1, 2, 3))
|
||||
|
||||
def testVertex(self):
|
||||
"""
|
||||
Tests basic vertex functions
|
||||
"""
|
||||
# Tests casting a vertex
|
||||
vc = Vertex.cast(Part.Vertex(1, 1, 1))
|
||||
self.assertEqual(1, vc.X)
|
||||
self.assertEqual(Vector, type(vc.Center()))
|
||||
|
||||
# Tests vertex instantiation
|
||||
v = Vertex(Part.Vertex(1, 1, 1))
|
||||
self.assertEqual(1, v.X)
|
||||
self.assertEqual(Vector, type(v.Center()))
|
||||
|
||||
def testFace(self):
|
||||
"""
|
||||
Test basic face functions, cast and instantiation
|
||||
"""
|
||||
edge1 = Part.makeLine((0, 0, 0), (0, 10, 0))
|
||||
edge2 = Part.makeLine((0, 10, 0), (10, 10, 0))
|
||||
edge3 = Part.makeLine((10, 10, 0), (10, 0, 0))
|
||||
edge4 = Part.makeLine((10, 0, 0), (0, 0, 0))
|
||||
wire1 = Part.Wire([edge1,edge2,edge3,edge4])
|
||||
face1 = Part.Face(wire1)
|
||||
|
||||
mplanec = Face.cast(face1)
|
||||
mplane = Face(face1)
|
||||
|
||||
self.assertTupleAlmostEquals((5.0, 5.0, 0.0), mplane.Center().toTuple(), 3)
|
||||
|
||||
def testShapeProps(self):
|
||||
"""
|
||||
Tests miscellaneous properties of the shape object
|
||||
"""
|
||||
e = Shape(Part.makeCircle(2.0, FreeCAD.Base.Vector(1, 2, 3)))
|
||||
|
||||
# Geometry type
|
||||
self.assertEqual(e.geomType(), 'Edge')
|
||||
|
||||
# Dynamic type checking
|
||||
self.assertTrue(e.isType(e, 'Edge'))
|
||||
self.assertFalse(e.isType(None, 'Edge'))
|
||||
|
||||
# Checking null objects
|
||||
self.assertFalse(e.isNull())
|
||||
|
||||
# Checking for sameness
|
||||
self.assertTrue(e.isSame(e))
|
||||
|
||||
# Checking for equality
|
||||
self.assertTrue(e.isEqual(e))
|
||||
|
||||
# Checking for shape validity
|
||||
self.assertTrue(e.isValid())
|
||||
|
||||
# Testing whether shape is closed
|
||||
self.assertTrue(e.Closed())
|
||||
|
||||
# Trying to get the area of the circular edge
|
||||
with self.assertRaises(ValueError):
|
||||
e.Area()
|
||||
|
||||
# Getting the area of the square face
|
||||
mplane = Face.makePlane(10.0, 10.0)
|
||||
self.assertAlmostEqual(100.0, mplane.Area(), 3)
|
||||
|
||||
# Getting the center of a solid
|
||||
s = Solid.makeCylinder(10.0, 10.0)
|
||||
self.assertTupleAlmostEquals((0.0, 0.0, 5.0), s.Center().toTuple(), 3)
|
||||
|
||||
def testBasicBoundingBox(self):
|
||||
v = Vertex(Part.Vertex(1, 1, 1))
|
||||
v2 = Vertex(Part.Vertex(2, 2, 2))
|
||||
|
@ -55,10 +166,57 @@ class TestCadObjects(BaseTest):
|
|||
self.assertTupleAlmostEquals((0.0, 0.0, 1.0), mplane.normalAt().toTuple(), 3)
|
||||
|
||||
def testCenterOfBoundBox(self):
|
||||
pass
|
||||
"""
|
||||
Tests whether or not a proper geometric center can be found for an object
|
||||
"""
|
||||
def cylinders(self, radius, height):
|
||||
def _cyl(pnt):
|
||||
# Inner function to build a cylinder
|
||||
return Solid.makeCylinder(radius, height, pnt)
|
||||
|
||||
# Combine all the cylinders into a single compound
|
||||
r = self.eachpoint(_cyl, True).combineSolids()
|
||||
|
||||
return r
|
||||
|
||||
Workplane.cyl = cylinders
|
||||
|
||||
# One solid in the compound
|
||||
s = Workplane("XY").pushPoints([(0.0, 0.0, 0.0)]).cyl(0.25, 0.5)
|
||||
self.assertEqual(1, len(s.val().Solids()))
|
||||
self.assertTupleAlmostEquals((0.0, 0.0, 0.25), s.val().CenterOfBoundBox().toTuple(), 2)
|
||||
|
||||
def testCombinedCenterOfBoundBox(self):
|
||||
pass
|
||||
"""
|
||||
Tests whether or not a proper geometric center can be found for multiple
|
||||
objects in a compound.
|
||||
"""
|
||||
def cylinders(self, radius, height):
|
||||
def _cyl(pnt):
|
||||
# Inner function to build a cylinder
|
||||
return Solid.makeCylinder(radius, height, pnt)
|
||||
|
||||
# Combine all the cylinders into a single compound
|
||||
r = self.eachpoint(_cyl, True).combineSolids()
|
||||
|
||||
return r
|
||||
|
||||
Workplane.cyl = cylinders
|
||||
|
||||
# Multiple solids in the compound
|
||||
s = Workplane("XY").rect(2.0, 3.0, forConstruction=True).vertices().cyl(0.25, 0.5)
|
||||
self.assertEqual(4, len(s.val().Solids()))
|
||||
self.assertTupleAlmostEquals((0.0, 0.0, 0.25), s.val().CenterOfBoundBox().toTuple(), 2)
|
||||
|
||||
def testCenter(self):
|
||||
"""
|
||||
Tests finding the center of shapes and solids
|
||||
"""
|
||||
circle = Workplane("XY").circle(10.0)
|
||||
cylinder = circle.extrude(10.0)
|
||||
|
||||
self.assertTupleAlmostEquals((0.0, 0.0, 0.0), circle.val().Center().toTuple(), 3)
|
||||
self.assertTupleAlmostEquals((0.0, 0.0, 5.0), cylinder.val().Center().toTuple(), 3)
|
||||
|
||||
def testCompoundCenter(self):
|
||||
"""
|
||||
|
@ -92,6 +250,39 @@ class TestCadObjects(BaseTest):
|
|||
self.assertIsInstance(result, Vector)
|
||||
self.assertTupleAlmostEquals((1.0, 2.0, 3.0), result.toTuple(), 3)
|
||||
|
||||
def testVectorArithmeticOverides(self):
|
||||
V = lambda x,y,z: Vector(x,y,z)
|
||||
self.assertEqual(V(1,2,3) + V(4,5,6), V(5,7,9)) # addition
|
||||
self.assertEqual(V(1,2,3) - V(5,4,3), V(-4,-2,0)) # subtraction
|
||||
self.assertEqual((V(1,2,3) * 2).toTuple(), (2,4,6)) # multiplication
|
||||
self.assertEqual((V(1,2,3) / 2).toTuple(), (0.5,1,1.5)) # division
|
||||
|
||||
def testVectorBoolCast(self):
|
||||
# zero vector
|
||||
self.assertEqual(bool(Vector(0,0,0)), False)
|
||||
# positive axes
|
||||
self.assertEqual(bool(Vector(1,0,0)), True)
|
||||
self.assertEqual(bool(Vector(0,1,0)), True)
|
||||
self.assertEqual(bool(Vector(0,0,1)), True)
|
||||
# negative axes
|
||||
self.assertEqual(bool(Vector(-1,0,0)), True)
|
||||
self.assertEqual(bool(Vector(0,-1,0)), True)
|
||||
self.assertEqual(bool(Vector(0,0,-1)), True)
|
||||
|
||||
def testVectorDivideByZero(self):
|
||||
with self.assertRaises(ZeroDivisionError):
|
||||
Vector(1, 2, 3) / 0
|
||||
|
||||
def testVectorLength(self):
|
||||
calc_length = lambda v: sqrt(v.x**2 + v.y**2 + v.z**2)
|
||||
vectors = [
|
||||
Vector(0,0,0), Vector(1,2,3), Vector(-1,-5,10),
|
||||
]
|
||||
for v in vectors:
|
||||
expected = calc_length(v)
|
||||
self.assertEqual(v.Length, expected)
|
||||
self.assertEqual(abs(v), expected)
|
||||
|
||||
def testVectorSub(self):
|
||||
result = Vector(1, 2, 3) - Vector(6, 5, 4)
|
||||
self.assertIsInstance(result, Vector)
|
||||
|
@ -116,12 +307,101 @@ class TestCadObjects(BaseTest):
|
|||
self.assertEqual(getattr(v, coord), new_val)
|
||||
setattr(v, coord, init_val)
|
||||
|
||||
def testVectorNegative(self):
|
||||
v = Vector(1, -2, 3)
|
||||
self.assertEqual(-v, Vector(-1, 2, -3))
|
||||
|
||||
def testShapeInit(self):
|
||||
"""
|
||||
Tests whether a Shape object can be instantiated without
|
||||
throwing an error.
|
||||
"""
|
||||
e = Shape(Part.makeCircle(2.0, FreeCAD.Base.Vector(1, 2, 3)))
|
||||
|
||||
def testPlaneEqual(self):
|
||||
# default orientation
|
||||
self.assertEqual(
|
||||
Plane(origin=(0,0,0), xDir=(1,0,0), normal=(0,0,1)),
|
||||
Plane(origin=(0,0,0), xDir=(1,0,0), normal=(0,0,1))
|
||||
)
|
||||
# moved origin
|
||||
self.assertEqual(
|
||||
Plane(origin=(2,1,-1), xDir=(1,0,0), normal=(0,0,1)),
|
||||
Plane(origin=(2,1,-1), xDir=(1,0,0), normal=(0,0,1))
|
||||
)
|
||||
# moved x-axis
|
||||
self.assertEqual(
|
||||
Plane(origin=(0,0,0), xDir=(1,1,0), normal=(0,0,1)),
|
||||
Plane(origin=(0,0,0), xDir=(1,1,0), normal=(0,0,1))
|
||||
)
|
||||
# moved z-axis
|
||||
self.assertEqual(
|
||||
Plane(origin=(0,0,0), xDir=(1,0,0), normal=(0,1,1)),
|
||||
Plane(origin=(0,0,0), xDir=(1,0,0), normal=(0,1,1))
|
||||
)
|
||||
|
||||
def testPlaneNotEqual(self):
|
||||
# type difference
|
||||
for value in [None, 0, 1, 'abc']:
|
||||
self.assertNotEqual(
|
||||
Plane(origin=(0,0,0), xDir=(1,0,0), normal=(0,0,1)),
|
||||
value
|
||||
)
|
||||
# origin difference
|
||||
self.assertNotEqual(
|
||||
Plane(origin=(0,0,0), xDir=(1,0,0), normal=(0,0,1)),
|
||||
Plane(origin=(0,0,1), xDir=(1,0,0), normal=(0,0,1))
|
||||
)
|
||||
# x-axis difference
|
||||
self.assertNotEqual(
|
||||
Plane(origin=(0,0,0), xDir=(1,0,0), normal=(0,0,1)),
|
||||
Plane(origin=(0,0,0), xDir=(1,1,0), normal=(0,0,1))
|
||||
)
|
||||
# z-axis difference
|
||||
self.assertNotEqual(
|
||||
Plane(origin=(0,0,0), xDir=(1,0,0), normal=(0,0,1)),
|
||||
Plane(origin=(0,0,0), xDir=(1,0,0), normal=(0,1,1))
|
||||
)
|
||||
|
||||
def testTranslate(self):
|
||||
e = Shape.cast(Part.makeCircle(2.0, FreeCAD.Base.Vector(1, 2, 3)))
|
||||
e2 = e.translate(Vector(0, 0, 1))
|
||||
|
||||
self.assertTupleAlmostEquals((1.0, 2.0, 4.0), e2.Center().toTuple(), 3)
|
||||
|
||||
def testScale(self):
|
||||
"""
|
||||
Tests scaling a shape and whether the dimensions are correct afterwards
|
||||
"""
|
||||
e = Shape.cast(Part.makeCircle(2.0, FreeCAD.Base.Vector(1, 2, 3)))
|
||||
e2 = e.scale(0.5)
|
||||
|
||||
self.assertAlmostEquals(2.0, e2.BoundingBox(tolerance=0.0001).xlen, 3)
|
||||
self.assertAlmostEquals(2.0, e2.BoundingBox(tolerance=0.0001).ylen, 3)
|
||||
|
||||
def testCopy(self):
|
||||
"""
|
||||
Tests making a copy of a shape object and whether the new one has the
|
||||
same properties as the original.
|
||||
"""
|
||||
e = Shape.cast(Part.makeCircle(2.0, FreeCAD.Base.Vector(1, 2, 3)))
|
||||
e2 = e.copy()
|
||||
|
||||
self.assertEquals(e.BoundingBox().xlen, e2.BoundingBox().xlen)
|
||||
self.assertEquals(e.BoundingBox().ylen, e2.BoundingBox().ylen)
|
||||
|
||||
def testRuledSurface(self):
|
||||
"""
|
||||
Tests making a ruled surface from two edges/wires.
|
||||
"""
|
||||
edge1 = Shape(Part.makeLine((0, 0, 5), (0, 10, 5)))
|
||||
edge2 = Shape(Part.makeLine((5, 5, 0), (10, 10, 0)))
|
||||
|
||||
surf1 = Face.makeRuledSurface(edge1, edge2)
|
||||
|
||||
self.assertEquals(surf1.ShapeType(), 'Face')
|
||||
self.assertTrue(surf1.isValid())
|
||||
|
||||
def testVertices(self):
|
||||
e = Shape.cast(Part.makeLine((0, 0, 0), (1, 1, 0)))
|
||||
self.assertEqual(2, len(e.Vertices()))
|
||||
|
|
|
@ -8,7 +8,15 @@ import math,sys,os.path,time
|
|||
#my modules
|
||||
from cadquery import *
|
||||
from cadquery import exporters
|
||||
from tests import BaseTest,writeStringToFile,makeUnitCube,readFileAsString,makeUnitSquareWire,makeCube
|
||||
from tests import (
|
||||
BaseTest,
|
||||
writeStringToFile,
|
||||
makeUnitCube,
|
||||
readFileAsString,
|
||||
makeUnitSquareWire,
|
||||
makeCube,
|
||||
)
|
||||
from cadquery.freecad_impl import suppress_stdout_stderr
|
||||
|
||||
#where unit test output will be saved
|
||||
import sys
|
||||
|
@ -73,10 +81,13 @@ class TestCadQuery(BaseTest):
|
|||
def saveModel(self, shape):
|
||||
"""
|
||||
shape must be a CQ object
|
||||
Save models in SVG and STEP format
|
||||
Save models in SVG, STEP and STL format
|
||||
"""
|
||||
shape.exportSvg(os.path.join(OUTDIR,self._testMethodName + ".svg"))
|
||||
shape.val().exportStep(os.path.join(OUTDIR,self._testMethodName + ".step"))
|
||||
|
||||
with suppress_stdout_stderr():
|
||||
shape.exportSvg(os.path.join(OUTDIR,self._testMethodName + ".svg"))
|
||||
shape.val().exportStep(os.path.join(OUTDIR,self._testMethodName + ".step"))
|
||||
shape.val().exportStl(os.path.join(OUTDIR,self._testMethodName + ".stl"))
|
||||
|
||||
def testToFreeCAD(self):
|
||||
"""
|
||||
|
@ -98,7 +109,6 @@ class TestCadQuery(BaseTest):
|
|||
|
||||
# Make sure that a couple of sections from the SVG output make sense
|
||||
self.assertTrue(r_str.index('path d=" M 2.35965 -2.27987 L 4.0114 -3.23936 "') > 0)
|
||||
self.assertTrue(r_str.index('line x1="30" y1="-30" x2="58" y2="-15" stroke-width="3"') > 0)
|
||||
|
||||
def testCubePlugin(self):
|
||||
"""
|
||||
|
@ -226,6 +236,42 @@ class TestCadQuery(BaseTest):
|
|||
self.assertEqual(type(r.val()), Solid)
|
||||
self.assertEqual(type(r.first().val()),Solid)
|
||||
|
||||
def testMirror(self):
|
||||
box = Workplane("XY").box(1, 1, 5)
|
||||
box2 = box.mirror()
|
||||
box3 = box.mirror("XZ")
|
||||
box4 = box.mirror("YZ")
|
||||
|
||||
# Box 2 (XY mirror)
|
||||
startPoint2 = box2.faces("<Y").edges("<X").first().val().startPoint().toTuple()
|
||||
endPoint2 = box2.faces("<Y").edges("<X").first().val().endPoint().toTuple()
|
||||
self.assertEqual(-0.5, startPoint2[0])
|
||||
self.assertEqual(-0.5, startPoint2[1])
|
||||
self.assertEqual(2.5, startPoint2[2])
|
||||
self.assertEqual(-0.5, endPoint2[0])
|
||||
self.assertEqual(-0.5, endPoint2[1])
|
||||
self.assertEqual(-2.5, endPoint2[2])
|
||||
|
||||
# Box 3 (XZ mirror)
|
||||
startPoint3 = box3.faces("<Y").edges("<X").first().val().startPoint().toTuple()
|
||||
endPoint3 = box3.faces("<Y").edges("<X").first().val().endPoint().toTuple()
|
||||
self.assertEqual(-0.5, startPoint3[0])
|
||||
self.assertEqual(-0.5, startPoint3[1])
|
||||
self.assertEqual(-2.5, startPoint3[2])
|
||||
self.assertEqual(-0.5, endPoint3[0])
|
||||
self.assertEqual(-0.5, endPoint3[1])
|
||||
self.assertEqual(2.5, endPoint3[2])
|
||||
|
||||
# Box 4 (YZ mirror)
|
||||
startPoint4 = box4.faces("<Y").edges("<X").first().val().startPoint().toTuple()
|
||||
endPoint4 = box4.faces("<Y").edges("<X").first().val().endPoint().toTuple()
|
||||
self.assertEqual(-0.5, startPoint4[0])
|
||||
self.assertEqual(-0.5, startPoint4[1])
|
||||
self.assertEqual(-2.5, startPoint4[2])
|
||||
self.assertEqual(-0.5, endPoint4[0])
|
||||
self.assertEqual(-0.5, endPoint4[1])
|
||||
self.assertEqual(2.5, endPoint4[2])
|
||||
|
||||
def testRotate(self):
|
||||
"""Test solid rotation at the CQ object level."""
|
||||
box = Workplane("XY").box(1, 1, 5)
|
||||
|
@ -648,7 +694,7 @@ class TestCadQuery(BaseTest):
|
|||
.threePointArc((5.793,1.293),(6.5,1))
|
||||
.lineTo(10,1)
|
||||
.close())
|
||||
|
||||
|
||||
result = result0.extrude(100)
|
||||
bb_center = result.val().BoundingBox().center
|
||||
self.saveModel(result)
|
||||
|
@ -681,7 +727,8 @@ class TestCadQuery(BaseTest):
|
|||
try:
|
||||
t = r.faces(">Y").workplane().circle(0.125).cutToOffsetFromFace(r.faces().mminDist(Dir.Y),0.1)
|
||||
self.assertEqual(10,t.faces().size() ) #should end up being a blind hole
|
||||
t.first().val().exportStep('c:/temp/testCutToFace.STEP')
|
||||
with suppress_stdout_stderr():
|
||||
t.first().val().exportStep('c:/temp/testCutToFace.STEP')
|
||||
except:
|
||||
pass
|
||||
#Not Implemented Yet
|
||||
|
@ -711,7 +758,8 @@ class TestCadQuery(BaseTest):
|
|||
#most users dont understand what a wire is, they are just drawing
|
||||
|
||||
r = s.lineTo(1.0,0).lineTo(0,1.0).close().wire().extrude(0.25)
|
||||
r.val().exportStep(os.path.join(OUTDIR, 'testBasicLinesStep1.STEP'))
|
||||
with suppress_stdout_stderr():
|
||||
r.val().exportStep(os.path.join(OUTDIR, 'testBasicLinesStep1.STEP'))
|
||||
|
||||
self.assertEqual(0,s.faces().size()) #no faces on the original workplane
|
||||
self.assertEqual(5,r.faces().size() ) # 5 faces on newly created object
|
||||
|
@ -719,12 +767,14 @@ class TestCadQuery(BaseTest):
|
|||
#now add a circle through a side face
|
||||
r.faces("+XY").workplane().circle(0.08).cutThruAll()
|
||||
self.assertEqual(6,r.faces().size())
|
||||
r.val().exportStep(os.path.join(OUTDIR, 'testBasicLinesXY.STEP'))
|
||||
with suppress_stdout_stderr():
|
||||
r.val().exportStep(os.path.join(OUTDIR, 'testBasicLinesXY.STEP'))
|
||||
|
||||
#now add a circle through a top
|
||||
r.faces("+Z").workplane().circle(0.08).cutThruAll()
|
||||
self.assertEqual(9,r.faces().size())
|
||||
r.val().exportStep(os.path.join(OUTDIR, 'testBasicLinesZ.STEP'))
|
||||
with suppress_stdout_stderr():
|
||||
r.val().exportStep(os.path.join(OUTDIR, 'testBasicLinesZ.STEP'))
|
||||
|
||||
self.saveModel(r)
|
||||
|
||||
|
@ -1275,6 +1325,80 @@ class TestCadQuery(BaseTest):
|
|||
line(-10,0).close().extrude(10,clean=False).clean()
|
||||
self.assertEqual(6, s.faces().size())
|
||||
|
||||
def testPlanes(self):
|
||||
"""
|
||||
Test other planes other than the normal ones (XY, YZ)
|
||||
"""
|
||||
# ZX plane
|
||||
s = Workplane(Plane.ZX())
|
||||
result = s.rect(2.0, 4.0).extrude(0.5).faces(">Z").workplane()\
|
||||
.rect(1.5, 3.5, forConstruction=True).vertices().cskHole(0.125, 0.25, 82, depth=None)
|
||||
self.saveModel(result)
|
||||
|
||||
# YX plane
|
||||
s = Workplane(Plane.YX())
|
||||
result = s.rect(2.0, 4.0).extrude(0.5).faces(">Z").workplane()\
|
||||
.rect(1.5, 3.5, forConstruction=True).vertices().cskHole(0.125, 0.25, 82, depth=None)
|
||||
self.saveModel(result)
|
||||
|
||||
# YX plane
|
||||
s = Workplane(Plane.YX())
|
||||
result = s.rect(2.0, 4.0).extrude(0.5).faces(">Z").workplane()\
|
||||
.rect(1.5, 3.5, forConstruction=True).vertices().cskHole(0.125, 0.25, 82, depth=None)
|
||||
self.saveModel(result)
|
||||
|
||||
# ZY plane
|
||||
s = Workplane(Plane.ZY())
|
||||
result = s.rect(2.0, 4.0).extrude(0.5).faces(">Z").workplane()\
|
||||
.rect(1.5, 3.5, forConstruction=True).vertices().cskHole(0.125, 0.25, 82, depth=None)
|
||||
self.saveModel(result)
|
||||
|
||||
# front plane
|
||||
s = Workplane(Plane.front())
|
||||
result = s.rect(2.0, 4.0).extrude(0.5).faces(">Z").workplane()\
|
||||
.rect(1.5, 3.5, forConstruction=True).vertices().cskHole(0.125, 0.25, 82, depth=None)
|
||||
self.saveModel(result)
|
||||
|
||||
# back plane
|
||||
s = Workplane(Plane.back())
|
||||
result = s.rect(2.0, 4.0).extrude(0.5).faces(">Z").workplane()\
|
||||
.rect(1.5, 3.5, forConstruction=True).vertices().cskHole(0.125, 0.25, 82, depth=None)
|
||||
self.saveModel(result)
|
||||
|
||||
# left plane
|
||||
s = Workplane(Plane.left())
|
||||
result = s.rect(2.0, 4.0).extrude(0.5).faces(">Z").workplane()\
|
||||
.rect(1.5, 3.5, forConstruction=True).vertices().cskHole(0.125, 0.25, 82, depth=None)
|
||||
self.saveModel(result)
|
||||
|
||||
# right plane
|
||||
s = Workplane(Plane.right())
|
||||
result = s.rect(2.0, 4.0).extrude(0.5).faces(">Z").workplane()\
|
||||
.rect(1.5, 3.5, forConstruction=True).vertices().cskHole(0.125, 0.25, 82, depth=None)
|
||||
self.saveModel(result)
|
||||
|
||||
# top plane
|
||||
s = Workplane(Plane.top())
|
||||
result = s.rect(2.0, 4.0).extrude(0.5).faces(">Z").workplane()\
|
||||
.rect(1.5, 3.5, forConstruction=True).vertices().cskHole(0.125, 0.25, 82, depth=None)
|
||||
self.saveModel(result)
|
||||
|
||||
# bottom plane
|
||||
s = Workplane(Plane.bottom())
|
||||
result = s.rect(2.0, 4.0).extrude(0.5).faces(">Z").workplane()\
|
||||
.rect(1.5, 3.5, forConstruction=True).vertices().cskHole(0.125, 0.25, 82, depth=None)
|
||||
self.saveModel(result)
|
||||
|
||||
def testIsIndide(self):
|
||||
"""
|
||||
Testing if one box is inside of another.
|
||||
"""
|
||||
box1 = Workplane(Plane.XY()).box(10, 10, 10)
|
||||
box2 = Workplane(Plane.XY()).box(5, 5, 5)
|
||||
|
||||
self.assertFalse(box2.val().BoundingBox().isInside(box1.val().BoundingBox()))
|
||||
self.assertTrue(box1.val().BoundingBox().isInside(box2.val().BoundingBox()))
|
||||
|
||||
def testCup(self):
|
||||
|
||||
"""
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
"""
|
||||
Tests basic workplane functionality
|
||||
"""
|
||||
#from __future__ import unicode_literals
|
||||
|
||||
#core modules
|
||||
import io
|
||||
|
||||
|
@ -18,13 +20,20 @@ class TestExporters(BaseTest):
|
|||
returns the result in case the case wants to do more checks also
|
||||
"""
|
||||
p = Workplane("XY").box(1,2,3)
|
||||
s = io.StringIO()
|
||||
exporters.exportShape(p,eType,s,0.1)
|
||||
|
||||
result = s.getvalue()
|
||||
#print result
|
||||
for q in stringsToFind:
|
||||
self.assertTrue(result.find(q) > -1 )
|
||||
if eType == exporters.ExportTypes.AMF:
|
||||
s = io.BytesIO()
|
||||
exporters.exportShape(p,eType,s,0.1)
|
||||
result = s.getvalue()
|
||||
for q in stringsToFind:
|
||||
self.assertTrue(result.decode().find(q) > -1 )
|
||||
else:
|
||||
s = io.StringIO()
|
||||
exporters.exportShape(p,eType,s,0.1)
|
||||
result = s.getvalue()
|
||||
for q in stringsToFind:
|
||||
self.assertTrue(q in result)
|
||||
|
||||
return result
|
||||
|
||||
def testSTL(self):
|
||||
|
|
|
@ -7,6 +7,7 @@ import io
|
|||
from cadquery import *
|
||||
from cadquery import exporters
|
||||
from cadquery import importers
|
||||
from cadquery.freecad_impl import suppress_stdout_stderr
|
||||
from tests import BaseTest
|
||||
|
||||
#where unit test output will be saved
|
||||
|
@ -35,10 +36,10 @@ class TestImporters(BaseTest):
|
|||
# Reimport the shape from the new STEP file
|
||||
importedShape = importers.importShape(importType,fileName)
|
||||
|
||||
#Check to make sure we got a solid back
|
||||
# Check to make sure we got a solid back
|
||||
self.assertTrue(importedShape.val().ShapeType() == "Solid")
|
||||
|
||||
#Check the number of faces and vertices per face to make sure we have a box shape
|
||||
# Check the number of faces and vertices per face to make sure we have a box shape
|
||||
self.assertTrue(importedShape.faces("+X").size() == 1 and importedShape.faces("+X").vertices().size() == 4)
|
||||
self.assertTrue(importedShape.faces("+Y").size() == 1 and importedShape.faces("+Y").vertices().size() == 4)
|
||||
self.assertTrue(importedShape.faces("+Z").size() == 1 and importedShape.faces("+Z").vertices().size() == 4)
|
||||
|
@ -47,7 +48,24 @@ class TestImporters(BaseTest):
|
|||
"""
|
||||
Tests STEP file import
|
||||
"""
|
||||
self.importBox(importers.ImportTypes.STEP, OUTDIR + "/tempSTEP.step")
|
||||
with suppress_stdout_stderr():
|
||||
self.importBox(importers.ImportTypes.STEP, OUTDIR + "/tempSTEP.step")
|
||||
|
||||
def testSTEPFromURL(self):
|
||||
"""
|
||||
Tests STEP file import from a URL
|
||||
"""
|
||||
stepURL = "https://raw.githubusercontent.com/dcowden/cadquery/master/doc/_static/box_export.step"
|
||||
|
||||
importedShape = importers.importStepFromURL(stepURL)
|
||||
|
||||
# Check to make sure we got a solid back
|
||||
self.assertTrue(importedShape.val().ShapeType() == "Solid")
|
||||
|
||||
# Check the number of faces and vertices per face to make sure we have a box shape
|
||||
self.assertTrue(importedShape.faces("+X").size() == 1 and importedShape.faces("+X").vertices().size() == 4)
|
||||
self.assertTrue(importedShape.faces("+Y").size() == 1 and importedShape.faces("+Y").vertices().size() == 4)
|
||||
self.assertTrue(importedShape.faces("+Z").size() == 1 and importedShape.faces("+Z").vertices().size() == 4)
|
||||
|
||||
if __name__ == '__main__':
|
||||
import unittest
|
||||
|
|
|
@ -2,6 +2,7 @@ from cadquery import *
|
|||
import unittest
|
||||
import sys
|
||||
import os
|
||||
from contextlib import contextmanager
|
||||
|
||||
import FreeCAD
|
||||
|
||||
|
@ -51,7 +52,7 @@ class BaseTest(unittest.TestCase):
|
|||
for i, j in zip(actual, expected):
|
||||
self.assertAlmostEqual(i, j, places)
|
||||
|
||||
__all__ = ['TestCadObjects', 'TestCadQuery', 'TestCQSelectors', 'TestWorkplanes', 'TestExporters', 'TestCQSelectors', 'TestImporters','TestCQGI']
|
||||
|
||||
__all__ = [
|
||||
'TestCQGI',
|
||||
'TestCQSelectors',
|
||||
|
|
|
@ -2,3 +2,4 @@ execute_on_save = False # Automatically execute a script every time you
|
|||
use_external_editor = False # Automatically reloads and executes a file when an external change is made
|
||||
max_line_length = 79 # The number of characters per line that is allowed before a warning is given
|
||||
font_size = 10 # Sets the font size of the Python editor
|
||||
execute_keybinding = 'F2' # The key(s) that is pressed to execute the currently active script
|
||||
|
|
Loading…
Reference in New Issue
Block a user