Merge branch 'master' into HEAD

git-svn-id: https://free-cad.svn.sourceforge.net/svnroot/free-cad/trunk@5407 e8eeb9e2-ec13-0410-a4a9-efa5cf37419d
This commit is contained in:
jriegel 2012-01-14 08:36:22 +00:00
commit 22ee2159ec
17 changed files with 962 additions and 101 deletions

View File

@ -1054,6 +1054,54 @@ void StdCmdViewAxo::activated(int iMsg)
doCommand(Command::Gui,"Gui.activeDocument().activeView().viewAxometric()");
}
//===========================================================================
// Std_ViewRotateLeft
//===========================================================================
DEF_3DV_CMD(StdCmdViewRotateLeft);
StdCmdViewRotateLeft::StdCmdViewRotateLeft()
: Command("Std_ViewRotateLeft")
{
sGroup = QT_TR_NOOP("Standard-View");
sMenuText = QT_TR_NOOP("Rotate Left");
sToolTipText = QT_TR_NOOP("Rotate the view by 90° counter-clockwise");
sWhatsThis = "Std_ViewXX";
sStatusTip = QT_TR_NOOP("Rotate the view by 90° counter-clockwise");
sPixmap = "view-rotate-left";
//sAccel = "Shift Left";
eType = Alter3DView;
}
void StdCmdViewRotateLeft::activated(int iMsg)
{
doCommand(Command::Gui,"Gui.activeDocument().activeView().viewRotateLeft()");
}
//===========================================================================
// Std_ViewRotateRight
//===========================================================================
DEF_3DV_CMD(StdCmdViewRotateRight);
StdCmdViewRotateRight::StdCmdViewRotateRight()
: Command("Std_ViewRotateRight")
{
sGroup = QT_TR_NOOP("Standard-View");
sMenuText = QT_TR_NOOP("Rotate Right");
sToolTipText = QT_TR_NOOP("Rotate the view by 90° clockwise");
sWhatsThis = "Std_ViewXX";
sStatusTip = QT_TR_NOOP("Rotate the view by 90° clockwise");
sPixmap = "view-rotate-right";
//sAccel = "Shift Right";
eType = Alter3DView;
}
void StdCmdViewRotateRight::activated(int iMsg)
{
doCommand(Command::Gui,"Gui.activeDocument().activeView().viewRotateRight()");
}
//===========================================================================
// Std_ViewFitAll
//===========================================================================
@ -2030,6 +2078,8 @@ void CreateViewStdCommands(void)
rcCmdMgr.addCommand(new StdCmdViewAxo());
rcCmdMgr.addCommand(new StdCmdViewFitAll());
rcCmdMgr.addCommand(new StdCmdViewFitSelection());
rcCmdMgr.addCommand(new StdCmdViewRotateLeft());
rcCmdMgr.addCommand(new StdCmdViewRotateRight());
rcCmdMgr.addCommand(new StdCmdViewExample1());
rcCmdMgr.addCommand(new StdCmdViewExample2());

View File

@ -86,6 +86,8 @@ EXTRA_DIST = \
view-zoom-in.svg \
view-zoom-out.svg \
view-zoom-selection.svg \
view-rotate-left.svg \
view-rotate-right.svg \
Tree_Annotation.svg \
Tree_Dimension.svg \
Tree_Python.svg \

View File

@ -68,6 +68,8 @@
<file>view-zoom-fit.svg</file>
<file>view-zoom-in.svg</file>
<file>view-zoom-out.svg</file>
<file>view-rotate-left.svg</file>
<file>view-rotate-right.svg</file>
<file>view-measurement.svg</file>
<file>view-zoom-selection.svg</file>
<file>Tree_Annotation.svg</file>

View File

@ -0,0 +1,230 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="64px"
height="64px"
id="svg6248"
sodipodi:version="0.32"
inkscape:version="0.48.1 r9760"
sodipodi:docname="view-rotate-left.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape"
version="1.1">
<defs
id="defs6250">
<linearGradient
id="linearGradient3253">
<stop
style="stop-color:#89d5f8;stop-opacity:1;"
offset="0"
id="stop3255" />
<stop
style="stop-color:#00899e;stop-opacity:1;"
offset="1"
id="stop3257" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3253"
id="radialGradient3270"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9781457,0.0053484,-0.00460223,0.8416912,-69.025653,-0.11788499)"
cx="10.328116"
cy="25.129232"
fx="10.328116"
fy="25.129232"
r="27.986705" />
<linearGradient
inkscape:collect="always"
id="linearGradient6816">
<stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop6818" />
<stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop6820" />
</linearGradient>
<linearGradient
id="linearGradient6781">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop6783" />
<stop
style="stop-color:#3465a4;stop-opacity:0;"
offset="1"
id="stop6785" />
</linearGradient>
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 32 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="64 : 32 : 1"
inkscape:persp3d-origin="32 : 21.333333 : 1"
id="perspective6256" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient6816"
id="radialGradient6822"
cx="33.369828"
cy="51.929391"
fx="33.369828"
fy="51.929391"
r="25.198714"
gradientTransform="matrix(1.1581633,0,0,0.6558985,-7.29237,16.126077)"
gradientUnits="userSpaceOnUse" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3393"
id="linearGradient3399"
x1="1669.7314"
y1="1726.0585"
x2="2067.1702"
y2="1726.0585"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9135837,0,0,0.9135837,138.63723,130.60625)" />
<linearGradient
id="linearGradient3393">
<stop
style="stop-color:#003ddd;stop-opacity:1;"
offset="0"
id="stop3395" />
<stop
style="stop-color:#639ef0;stop-opacity:1;"
offset="1"
id="stop3397" />
</linearGradient>
<linearGradient
y2="1726.0585"
x2="2067.1702"
y1="1726.0585"
x1="1669.7314"
gradientTransform="matrix(0.9135837,0,0,0.9135837,138.63723,130.60625)"
gradientUnits="userSpaceOnUse"
id="linearGradient3270"
xlink:href="#linearGradient3393"
inkscape:collect="always" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3253"
id="radialGradient3293"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9781457,0.0053484,-0.00460223,0.8416912,-69.025653,-0.11788499)"
cx="10.328116"
cy="25.129232"
fx="10.328116"
fy="25.129232"
r="27.986705" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3253-6"
id="radialGradient3270-0"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.2166851,1.0433407,-0.52714011,0.61472119,-73.012055,-80.803852)"
cx="83.590195"
cy="32.60199"
fx="83.590195"
fy="32.60199"
r="27.986706" />
<linearGradient
id="linearGradient3253-6">
<stop
style="stop-color:#89d5f8;stop-opacity:1;"
offset="0"
id="stop3255-8" />
<stop
style="stop-color:#00899e;stop-opacity:1;"
offset="1"
id="stop3257-7" />
</linearGradient>
<radialGradient
r="27.986706"
fy="25.129232"
fx="10.328116"
cy="25.129232"
cx="10.328116"
gradientTransform="matrix(0.9781457,0.0053484,-0.00460223,0.8416912,-2.1599239,-18.716253)"
gradientUnits="userSpaceOnUse"
id="radialGradient3337"
xlink:href="#linearGradient3253-6"
inkscape:collect="always" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3253-6-5"
id="radialGradient3270-0-1"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.2166851,1.0433407,-0.52714011,0.61472119,-73.012055,-80.803852)"
cx="83.590195"
cy="32.60199"
fx="83.590195"
fy="32.60199"
r="27.986706" />
<linearGradient
id="linearGradient3253-6-5">
<stop
style="stop-color:#89d5f8;stop-opacity:1;"
offset="0"
id="stop3255-8-4" />
<stop
style="stop-color:#00899e;stop-opacity:1;"
offset="1"
id="stop3257-7-9" />
</linearGradient>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="5.5"
inkscape:cx="19.843715"
inkscape:cy="32.297511"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:document-units="px"
inkscape:grid-bbox="true"
inkscape:window-width="1278"
inkscape:window-height="723"
inkscape:window-x="2"
inkscape:window-y="54"
inkscape:window-maximized="0" />
<metadata
id="metadata6253">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer">
<path
style="opacity:0.525;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.07951307;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="M 56.76028,22.360887 C 49.477414,12.499951 36.263904,9.6341851 25.68422,15.000413 L 20.182888,7.5516576 8.328905,34.770245 37.830019,31.445717 32.042903,23.610013 c 5.788375,-2.083823 12.481522,-0.255822 16.325436,4.948805 4.694273,6.356002 3.34635,15.319498 -3.009652,20.013771 -5.510536,4.069847 -12.976826,3.600229 -17.925875,-0.739333 l -8.512862,6.287237 c 8.478061,8.931514 22.496324,10.370637 32.654528,2.868221 10.996126,-8.121271 13.307072,-23.6317 5.185802,-34.627827 z"
id="path3295-2"
inkscape:connector-curvature="0" />
<path
style="color:#000000;fill:url(#radialGradient3270-0);fill-opacity:1;fill-rule:nonzero;stroke:#004c5b;stroke-width:2.07951306999999996;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="M 51.959599,18.041333 C 44.676733,8.1803975 31.463223,5.3146312 20.883539,10.680859 L 15.382207,3.2321037 3.5282239,30.45069 33.029338,27.126162 27.242222,19.290459 c 5.788375,-2.083823 12.481522,-0.255822 16.325436,4.948804 4.694273,6.356002 3.34635,15.319498 -3.009652,20.013771 -5.510536,4.069847 -12.976826,3.600229 -17.925875,-0.739333 l -8.512862,6.287237 c 8.478061,8.931514 22.496324,10.370637 32.654528,2.868221 10.996126,-8.121271 13.307072,-23.6317 5.185802,-34.627826 z"
id="path3295"
inkscape:connector-curvature="0" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 8.2 KiB

View File

@ -0,0 +1,242 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="64px"
height="64px"
id="svg6248"
sodipodi:version="0.32"
inkscape:version="0.48.1 r9760"
sodipodi:docname="view-rotate-right.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape"
version="1.1">
<defs
id="defs6250">
<linearGradient
id="linearGradient3253">
<stop
style="stop-color:#89d5f8;stop-opacity:1;"
offset="0"
id="stop3255" />
<stop
style="stop-color:#00899e;stop-opacity:1;"
offset="1"
id="stop3257" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient6816">
<stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop6818" />
<stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop6820" />
</linearGradient>
<linearGradient
id="linearGradient6781">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop6783" />
<stop
style="stop-color:#3465a4;stop-opacity:0;"
offset="1"
id="stop6785" />
</linearGradient>
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 32 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="64 : 32 : 1"
inkscape:persp3d-origin="32 : 21.333333 : 1"
id="perspective6256" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient6816"
id="radialGradient6822"
cx="33.369828"
cy="51.929391"
fx="33.369828"
fy="51.929391"
r="25.198714"
gradientTransform="matrix(1.1581633,0,0,0.6558985,-7.29237,16.126077)"
gradientUnits="userSpaceOnUse" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3393"
id="linearGradient3399"
x1="1669.7314"
y1="1726.0585"
x2="2067.1702"
y2="1726.0585"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9135837,0,0,0.9135837,138.63723,130.60625)" />
<linearGradient
id="linearGradient3393">
<stop
style="stop-color:#003ddd;stop-opacity:1;"
offset="0"
id="stop3395" />
<stop
style="stop-color:#639ef0;stop-opacity:1;"
offset="1"
id="stop3397" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3253-6"
id="radialGradient3270-0"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.5248767,0.58857909,0.29159851,-0.75546618,-132.2862,-41.872415)"
cx="96.579445"
cy="-3.6412485"
fx="96.579445"
fy="-3.6412485"
r="27.986706" />
<linearGradient
id="linearGradient3253-6">
<stop
style="stop-color:#89d5f8;stop-opacity:1;"
offset="0"
id="stop3255-8" />
<stop
style="stop-color:#00899e;stop-opacity:1;"
offset="1"
id="stop3257-7" />
</linearGradient>
<radialGradient
r="27.986706"
fy="25.129232"
fx="10.328116"
cy="25.129232"
cx="10.328116"
gradientTransform="matrix(0.9781457,0.0053484,-0.00460223,0.8416912,-2.1599239,-18.716253)"
gradientUnits="userSpaceOnUse"
id="radialGradient3337"
xlink:href="#linearGradient3253-6"
inkscape:collect="always" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3253-6-5"
id="radialGradient3270-0-1"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.2166851,1.0433407,-0.52714011,0.61472119,-73.012055,-80.803852)"
cx="83.590195"
cy="32.60199"
fx="83.590195"
fy="32.60199"
r="27.986706" />
<linearGradient
id="linearGradient3253-6-5">
<stop
style="stop-color:#89d5f8;stop-opacity:1;"
offset="0"
id="stop3255-8-4" />
<stop
style="stop-color:#00899e;stop-opacity:1;"
offset="1"
id="stop3257-7-9" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3253-6-6"
id="radialGradient3270-0-6"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.2166851,1.0433407,-0.52714011,0.61472119,-145.06148,-79.720497)"
cx="83.590195"
cy="32.60199"
fx="83.590195"
fy="32.60199"
r="27.986706" />
<linearGradient
id="linearGradient3253-6-6">
<stop
style="stop-color:#89d5f8;stop-opacity:1;"
offset="0"
id="stop3255-8-2" />
<stop
style="stop-color:#00899e;stop-opacity:1;"
offset="1"
id="stop3257-7-1" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3253-6-3"
id="radialGradient3270-0-4"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.5248767,0.58857909,0.29159851,-0.75546618,-132.2862,-41.872415)"
cx="96.579445"
cy="-3.6412485"
fx="96.579445"
fy="-3.6412485"
r="27.986706" />
<linearGradient
id="linearGradient3253-6-3">
<stop
style="stop-color:#89d5f8;stop-opacity:1;"
offset="0"
id="stop3255-8-9" />
<stop
style="stop-color:#00899e;stop-opacity:1;"
offset="1"
id="stop3257-7-7" />
</linearGradient>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="7.7781746"
inkscape:cx="28.910249"
inkscape:cy="33.443764"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:document-units="px"
inkscape:grid-bbox="true"
inkscape:window-width="1278"
inkscape:window-height="723"
inkscape:window-x="2"
inkscape:window-y="54"
inkscape:window-maximized="0" />
<metadata
id="metadata6253">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer">
<path
style="opacity:0.525;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.07951307;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="M 13.300273,22.764586 C 20.58314,12.903651 33.79665,10.037884 44.376334,15.404112 L 49.877666,7.9553569 61.731649,35.173943 32.230535,31.849415 38.017651,24.013712 c -5.788375,-2.083823 -12.481522,-0.255822 -16.325436,4.948804 -4.694274,6.356002 -3.34635,15.319498 3.009652,20.013771 5.510536,4.069847 12.976826,3.600229 17.925875,-0.739333 l 8.512862,6.287237 C 42.662543,63.455705 28.64428,64.894828 18.486076,57.392412 7.4899493,49.271141 5.1790034,33.760712 13.300273,22.764586 z"
id="path3295-2"
inkscape:connector-curvature="0" />
<path
style="color:#000000;fill:url(#radialGradient3270-0);fill-opacity:1;fill-rule:nonzero;stroke:#004c5b;stroke-width:2.07951306999999996;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="M 8.3783278,18.041333 C 15.661194,8.1803975 28.874704,5.3146312 39.454388,10.680859 L 44.95572,3.2321037 56.809703,30.45069 27.308589,27.126162 33.095705,19.290459 c -5.788375,-2.083823 -12.481522,-0.255822 -16.325436,4.948804 -4.694273,6.356002 -3.34635,15.319498 3.009652,20.013771 5.510536,4.069847 12.976826,3.600229 17.925875,-0.739333 l 8.512862,6.287237 C 37.740597,58.732452 23.722334,60.171575 13.56413,52.669159 2.5680038,44.547888 0.25705785,29.037459 8.3783278,18.041333 z"
id="path3295"
inkscape:connector-curvature="0" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 8.5 KiB

View File

@ -76,6 +76,8 @@ void View3DInventorPy::init_type()
add_varargs_method("viewRight",&View3DInventorPy::viewRight,"viewRight()");
add_varargs_method("viewTop",&View3DInventorPy::viewTop,"viewTop()");
add_varargs_method("viewAxometric",&View3DInventorPy::viewAxometric,"viewAxometric()");
add_varargs_method("viewRotateLeft",&View3DInventorPy::viewRotateLeft,"viewRotateLeft()");
add_varargs_method("viewRotateRight",&View3DInventorPy::viewRotateRight,"viewRotateRight()");
add_varargs_method("viewPosition",&View3DInventorPy::viewPosition,"viewPosition()");
add_varargs_method("startAnimating",&View3DInventorPy::startAnimating,"startAnimating()");
add_varargs_method("stopAnimating",&View3DInventorPy::stopAnimating,"stopAnimating()");
@ -407,6 +409,58 @@ Py::Object View3DInventorPy::viewAxometric(const Py::Tuple& args)
return Py::None();
}
Py::Object View3DInventorPy::viewRotateLeft(const Py::Tuple& args)
{
if (!PyArg_ParseTuple(args.ptr(), ""))
throw Py::Exception();
try {
SoCamera* cam = _view->getViewer()->getCamera();
SbRotation rot = cam->orientation.getValue();
SbVec3f vdir(0, 0, -1);
rot.multVec(vdir, vdir);
SbRotation nrot(vdir, M_PI/2);
cam->orientation.setValue(rot*nrot);
}
catch (const Base::Exception& e) {
throw Py::Exception(e.what());
}
catch (const std::exception& e) {
throw Py::Exception(e.what());
}
catch(...) {
throw Py::Exception("Unknown C++ exception");
}
return Py::None();
}
Py::Object View3DInventorPy::viewRotateRight(const Py::Tuple& args)
{
if (!PyArg_ParseTuple(args.ptr(), ""))
throw Py::Exception();
try {
SoCamera* cam = _view->getViewer()->getCamera();
SbRotation rot = cam->orientation.getValue();
SbVec3f vdir(0, 0, -1);
rot.multVec(vdir, vdir);
SbRotation nrot(vdir, -M_PI/2);
cam->orientation.setValue(rot*nrot);
}
catch (const Base::Exception& e) {
throw Py::Exception(e.what());
}
catch (const std::exception& e) {
throw Py::Exception(e.what());
}
catch(...) {
throw Py::Exception("Unknown C++ exception");
}
return Py::None();
}
Py::Object View3DInventorPy::setCameraOrientation(const Py::Tuple& args)
{
PyObject* o;

View File

@ -55,6 +55,8 @@ public:
Py::Object viewTop(const Py::Tuple&);
Py::Object viewAxometric(const Py::Tuple&);
Py::Object viewPosition(const Py::Tuple&);
Py::Object viewRotateLeft(const Py::Tuple&);
Py::Object viewRotateRight(const Py::Tuple&);
Py::Object startAnimating(const Py::Tuple&);
Py::Object stopAnimating(const Py::Tuple&);
Py::Object setAnimationEnabled(const Py::Tuple&);

View File

@ -395,7 +395,8 @@ void StdWorkbench::setupContextMenu(const char* recipient, MenuItem* item) const
StdViews->setCommand( "Standard views" );
*StdViews << "Std_ViewAxo" << "Separator" << "Std_ViewFront" << "Std_ViewTop" << "Std_ViewRight"
<< "Std_ViewRear" << "Std_ViewBottom" << "Std_ViewLeft";
<< "Std_ViewRear" << "Std_ViewBottom" << "Std_ViewLeft"
<< "Separator" << "Std_ViewRotateLeft" << "Std_ViewRotateRight";
*item << "Std_ViewFitAll" << "Std_ViewFitSelection" << StdViews
<< "Separator" << "Std_ViewDockUndockFullscreen";
@ -447,7 +448,8 @@ MenuItem* StdWorkbench::setupMenuBar() const
*stdviews << "Std_ViewFitAll" << "Std_ViewFitSelection" << "Std_ViewAxo"
<< "Separator" << "Std_ViewFront" << "Std_ViewRight"
<< "Std_ViewTop" << "Separator" << "Std_ViewRear"
<< "Std_ViewLeft" << "Std_ViewBottom";
<< "Std_ViewLeft" << "Std_ViewBottom"
<< "Separator" << "Std_ViewRotateLeft" << "Std_ViewRotateRight";
// stereo
MenuItem* view3d = new MenuItem;

View File

@ -21,10 +21,10 @@
#* *
#***************************************************************************
import FreeCAD,FreeCADGui,Draft,ArchComponent,math
import FreeCAD,FreeCADGui,Draft,math
from draftlibs import fcvec
from FreeCAD import Vector
from PyQt4 import QtCore
from PyQt4 import QtCore, QtGui
from pivy import coin
__title__="FreeCAD Axis System"
@ -61,17 +61,15 @@ class _CommandAxis:
makeAxis(5,1)
FreeCAD.ActiveDocument.commitTransaction()
class _Axis(ArchComponent.Component):
class _Axis:
"The Axis object"
def __init__(self,obj):
obj.addProperty("App::PropertyFloatList","Distances","Base", "The intervals between axes")
obj.addProperty("App::PropertyFloatList","Angles","Base", "The angles of each axis")
obj.addProperty("App::PropertyFloatList","Limits","Base", "The inferior and superior drawing limits")
obj.addProperty("App::PropertyFloat","Length","Base", "The length of the axes")
self.Type = "Axis"
obj.Limits=[0.0,1.0]
obj.Length=1.0
obj.Proxy = self
self.Object = obj
def execute(self,obj):
self.createGeometry(obj)
@ -90,25 +88,29 @@ class _Axis(ArchComponent.Component):
for i in range(len(obj.Distances)):
dist += obj.Distances[i]
ang = math.radians(obj.Angles[i])
p1 = Vector(dist,obj.Limits[0],0)
p2 = Vector(dist+(obj.Limits[1]/math.cos(ang))*math.sin(ang),obj.Limits[1],0)
p1 = Vector(dist,0,0)
p2 = Vector(dist+(obj.Length/math.cos(ang))*math.sin(ang),obj.Length,0)
geoms.append(Part.Line(p1,p2).toShape())
if geoms:
obj.Shape = Part.Compound(geoms)
obj.Placement = pl
class _ViewProviderAxis(ArchComponent.ViewProviderComponent):
class _ViewProviderAxis:
"A View Provider for the Axis object"
def __init__(self,vobj):
vobj.addProperty("App::PropertyLength","BubbleSize","Base", "The size of the axis bubbles")
vobj.addProperty("App::PropertyEnumeration","NumerationStyle","Base", "The numeration style")
vobj.NumerationStyle = ["1,2,3","01,02,03","A,B,C","a,b,c","I,II,III"]
vobj.addProperty("App::PropertyEnumeration","DrawStyle","Base", "The representation style")
vobj.NumerationStyle = ["1,2,3","01,02,03","001,002,003","A,B,C","a,b,c","I,II,III","L0,L1,L2"]
vobj.DrawStyle = ["solid","dotted","dashed","dashdot"]
vobj.Proxy = self
self.Object = vobj.Object
self.ViewObject = vobj
vobj.BubbleSize = .1
vobj.LineWidth = 1
vobj.LineColor = (0.13,0.15,0.37)
vobj.DrawStyle = "dashdot"
def getIcon(self):
return ":/icons/Arch_Axis_Tree.svg"
@ -117,10 +119,59 @@ class _ViewProviderAxis(ArchComponent.ViewProviderComponent):
return []
def attach(self, vobj):
self.Object = vobj.Object
self.ViewObject = vobj
self.bubbles = None
def getNumber(self,num):
chars = "abcdefghijklmnopqrstuvwxyz"
roman=(('M',1000),('CM',900),('D',500),('CD',400),
('C',100),('XC',90),('L',50),('XL',40),
('X',10),('IX',9),('V',5),('IV',4),('I',1))
if self.ViewObject.NumerationStyle == "1,2,3":
return str(num+1)
elif self.ViewObject.NumerationStyle == "01,02,03":
return str(num+1).zfill(2)
elif self.ViewObject.NumerationStyle == "001,002,003":
return str(num+1).zfill(3)
elif self.ViewObject.NumerationStyle == "A,B,C":
result = ""
base = num/26
if base:
result += chars[base].upper()
remainder = num % 26
result += chars[remainder].upper()
return result
elif self.ViewObject.NumerationStyle == "a,b,c":
result = ""
base = num/26
if base:
result += chars[base]
remainder = num % 26
result += chars[remainder]
return result
elif self.ViewObject.NumerationStyle == "I,II,III":
result = ""
num += 1
for numeral, integer in roman:
while num >= integer:
result += numeral
num -= integer
return result
elif self.ViewObject.NumerationStyle == "L0,L1,L2":
return "L"+str(num)
return ""
def setStyle(self):
ds = self.ViewObject.RootNode.getChild(2).getChild(0).getChild(0).getChild(1)
if self.ViewObject.DrawStyle == "solid":
ds.linePattern = 0xffff
elif self.ViewObject.DrawStyle == "dotted":
ds.linePattern = 0x0f0f
elif self.ViewObject.DrawStyle == "dashed":
ds.linePattern = 0xf00f
elif self.ViewObject.DrawStyle == "dashdot":
ds.linePattern = 0xff88
def makeBubbles(self):
import Part
rn = self.ViewObject.RootNode.getChild(2).getChild(0).getChild(0)
@ -128,9 +179,13 @@ class _ViewProviderAxis(ArchComponent.ViewProviderComponent):
rn.removeChild(self.bubbles)
self.bubbles = None
self.bubbles = coin.SoSeparator()
for i in range(len(self.Object.Distances)):
invpl = self.Object.Placement.inverse()
verts = self.Object.Shape.Edges[i].Vertexes
isep = coin.SoSeparator()
self.bubblestyle = coin.SoDrawStyle()
self.bubblestyle.linePattern = 0xffff
self.bubbles.addChild(self.bubblestyle)
for i in range(len(self.ViewObject.Object.Distances)):
invpl = self.ViewObject.Object.Placement.inverse()
verts = self.ViewObject.Object.Shape.Edges[i].Vertexes
p1 = invpl.multVec(verts[0].Point)
p2 = invpl.multVec(verts[1].Point)
dv = p2.sub(p1)
@ -153,12 +208,12 @@ class _ViewProviderAxis(ArchComponent.ViewProviderComponent):
fo.size = rad*100
tx = coin.SoText2()
tx.justification = coin.SoText2.CENTER
tx.string = str(i)
tx.string = self.getNumber(i)
st.addChild(tr)
st.addChild(fo)
st.addChild(tx)
self.bubbles.addChild(st)
isep.addChild(st)
self.bubbles.addChild(isep)
rn.addChild(self.bubbles)
def updateData(self, obj, prop):
@ -169,7 +224,140 @@ class _ViewProviderAxis(ArchComponent.ViewProviderComponent):
def onChanged(self, vobj, prop):
if prop in ["NumerationStyle","BubbleSize"]:
self.makeBubbles()
elif prop == "DrawStyle":
self.setStyle()
elif prop == "LineWidth":
if self.bubbles:
self.bubblestyle.lineWidth = vobj.LineWidth
return
def setEdit(self,vobj,mode):
taskd = _AxisTaskPanel()
taskd.obj = vobj.Object
taskd.update()
FreeCADGui.Control.showDialog(taskd)
return True
def unsetEdit(self,vobj,mode):
FreeCADGui.Control.closeDialog()
return
def __getstate__(self):
return None
def __setstate__(self,state):
return None
class _AxisTaskPanel:
'''The editmode TaskPanel for Axis objects'''
def __init__(self):
# the panel has a tree widget that contains categories
# for the subcomponents, such as additions, subtractions.
# the categories are shown only if they are not empty.
self.obj = None
self.form = QtGui.QWidget()
self.form.setObjectName("TaskPanel")
self.grid = QtGui.QGridLayout(self.form)
self.grid.setObjectName("grid")
self.title = QtGui.QLabel(self.form)
self.grid.addWidget(self.title, 0, 0, 1, 2)
# tree
self.tree = QtGui.QTreeWidget(self.form)
self.grid.addWidget(self.tree, 1, 0, 1, 2)
self.tree.setColumnCount(3)
self.tree.header().resizeSection(0,50)
self.tree.header().resizeSection(1,80)
self.tree.header().resizeSection(2,60)
# buttons
self.addButton = QtGui.QPushButton(self.form)
self.addButton.setObjectName("addButton")
self.addButton.setIcon(QtGui.QIcon(":/icons/Arch_Add.svg"))
self.grid.addWidget(self.addButton, 3, 0, 1, 1)
self.addButton.setEnabled(True)
self.delButton = QtGui.QPushButton(self.form)
self.delButton.setObjectName("delButton")
self.delButton.setIcon(QtGui.QIcon(":/icons/Arch_Remove.svg"))
self.grid.addWidget(self.delButton, 3, 1, 1, 1)
self.delButton.setEnabled(True)
self.okButton = QtGui.QPushButton(self.form)
self.okButton.setObjectName("okButton")
self.okButton.setIcon(QtGui.QIcon(":/icons/edit_OK.svg"))
self.grid.addWidget(self.okButton, 4, 0, 1, 2)
QtCore.QObject.connect(self.addButton, QtCore.SIGNAL("clicked()"), self.addElement)
QtCore.QObject.connect(self.delButton, QtCore.SIGNAL("clicked()"), self.removeElement)
QtCore.QObject.connect(self.okButton, QtCore.SIGNAL("clicked()"), self.finish)
self.update()
def isAllowedAlterSelection(self):
return False
def isAllowedAlterView(self):
return True
def getStandardButtons(self):
return 0
def update(self):
'fills the treewidget'
self.tree.clear()
if self.obj:
for i in range(len(self.obj.Distances)):
item = QtGui.QTreeWidgetItem(self.tree)
item.setText(0,str(i+1))
item.setText(1,str(self.obj.Distances[i]))
item.setText(2,str(self.obj.Angles[i]))
item.setFlags(item.flags() | QtCore.Qt.ItemIsEditable)
item.setTextAlignment(0,QtCore.Qt.AlignLeft)
self.retranslateUi(self.form)
def addElement(self):
item = QtGui.QTreeWidgetItem(self.tree)
item.setText(0,str(self.tree.topLevelItemCount()))
item.setText(1,"1.0")
item.setText(2,"0.0")
item.setFlags(item.flags() | QtCore.Qt.ItemIsEditable)
self.resetObject()
def removeElement(self):
it = self.tree.currentItem()
if it:
nr = int(it.text(0))-1
self.resetObject(remove=nr)
self.update()
def resetObject(self,remove=None):
d = []
a = []
for i in range(self.tree.topLevelItemCount()):
it = self.tree.findItems(str(i+1),QtCore.Qt.MatchExactly,0)[0]
if (remove == None) or (remove != i):
d.append(float(it.text(1)))
a.append(float(it.text(2)))
self.obj.Distances = d
self.obj.Angles = a
FreeCAD.ActiveDocument.recompute()
def finish(self):
self.resetObject()
if self.obj:
self.obj.ViewObject.finishEditing()
def retranslateUi(self, TaskPanel):
TaskPanel.setWindowTitle(QtGui.QApplication.translate("Arch", "Axes", None, QtGui.QApplication.UnicodeUTF8))
self.delButton.setText(QtGui.QApplication.translate("Arch", "Remove", None, QtGui.QApplication.UnicodeUTF8))
self.addButton.setText(QtGui.QApplication.translate("Arch", "Add", None, QtGui.QApplication.UnicodeUTF8))
self.okButton.setText(QtGui.QApplication.translate("Arch", "Done", None, QtGui.QApplication.UnicodeUTF8))
self.title.setText(QtGui.QApplication.translate("Arch", "Distances and angles between axes", None, QtGui.QApplication.UnicodeUTF8))
self.tree.setHeaderLabels([QtGui.QApplication.translate("Arch", "Axis", None, QtGui.QApplication.UnicodeUTF8),
QtGui.QApplication.translate("Arch", "Distance", None, QtGui.QApplication.UnicodeUTF8),
QtGui.QApplication.translate("Arch", "Angle", None, QtGui.QApplication.UnicodeUTF8)])
FreeCADGui.addCommand('Arch_Axis',_CommandAxis())

View File

@ -34,6 +34,7 @@ def addToComponent(compobject,addobject,mod=None):
"Components", the first one that exists in the component. Mod
can be set to one of those attributes ("Objects", Base", etc...)
to override the default.'''
import Draft
if compobject == addobject: return
# first check is already there
found = False
@ -51,11 +52,17 @@ def addToComponent(compobject,addobject,mod=None):
if hasattr(compobject,mod):
if mod == "Base":
setattr(compobject,mod,addobject)
addobject.ViewObject.hide()
elif mod == "Axes":
if Draft.getType(addobject) == "Axis":
l = getattr(compobject,mod)
l.append(addobject)
setattr(compobject,mod,l)
else:
l = getattr(compobject,mod)
l.append(addobject)
setattr(compobject,mod,l)
addobject.ViewObject.hide()
addobject.ViewObject.hide()
else:
for a in attribs[:3]:
if hasattr(compobject,a):
@ -103,7 +110,7 @@ class ComponentTaskPanel:
# the categories are shown only if they are not empty.
self.obj = None
self.attribs = ["Base","Additions","Subtractions","Objects","Components"]
self.attribs = ["Base","Additions","Subtractions","Objects","Components","Axes"]
self.form = QtGui.QWidget()
self.form.setObjectName("TaskPanel")
self.grid = QtGui.QGridLayout(self.form)
@ -150,9 +157,6 @@ class ComponentTaskPanel:
def getStandardButtons(self):
return 0
def removeElement(self):
return
def check(self,wid,col):
if not wid.parent():
self.delButton.setEnabled(False)
@ -236,6 +240,7 @@ class ComponentTaskPanel:
self.treeAdditions.setText(0,QtGui.QApplication.translate("Arch", "Additions", None, QtGui.QApplication.UnicodeUTF8))
self.treeSubtractions.setText(0,QtGui.QApplication.translate("Arch", "Subtractions", None, QtGui.QApplication.UnicodeUTF8))
self.treeObjects.setText(0,QtGui.QApplication.translate("Arch", "Objects", None, QtGui.QApplication.UnicodeUTF8))
self.treeAxes.setText(0,QtGui.QApplication.translate("Arch", "Axes", None, QtGui.QApplication.UnicodeUTF8))
self.treeComponents.setText(0,QtGui.QApplication.translate("Arch", "Components", None, QtGui.QApplication.UnicodeUTF8))
class Component:
@ -251,7 +256,6 @@ class Component:
"The normal extrusion direction of this wall (keep (0,0,0) for automatic normal)")
obj.Proxy = self
self.Type = "Component"
self.Object = obj
self.Subvolume = None

View File

@ -84,15 +84,32 @@ class _Structure(ArchComponent.Component):
"The width of this element, if not based on a profile")
obj.addProperty("App::PropertyLength","Height","Base",
"The height or extrusion depth of this element. Keep 0 for automatic")
obj.addProperty("App::PropertyLinkList","Axes","Base",
"Axes systems this structure is built on")
self.Type = "Structure"
def execute(self,obj):
self.createGeometry(obj)
def onChanged(self,obj,prop):
if prop in ["Base","Length","Width","Height","Normal","Additions","Subtractions"]:
if prop in ["Base","Length","Width","Height","Normal","Additions","Subtractions","Axes"]:
self.createGeometry(obj)
def getAxisPoints(self,obj):
"returns the gridpoints of linked axes"
from draftlibs import fcgeo
pts = []
if len(obj.Axes) == 1:
for e in obj.Axes[0].Shape.Edges:
pts.append(e.Vertexes[0].Point)
elif len(obj.Axes) >= 2:
set1 = obj.Axes[0].Shape.Edges
set2 = obj.Axes[1].Shape.Edges
for e1 in set1:
for e2 in set2:
pts.extend(fcgeo.findIntersection(e1,e2))
return pts
def createGeometry(self,obj):
import Part
from draftlibs import fcgeo
@ -158,7 +175,16 @@ class _Structure(ArchComponent.Component):
base = base.cut(hole.Shape)
hole.ViewObject.hide() # to be removed
if base:
obj.Shape = base
pts = self.getAxisPoints(obj)
if pts:
fsh = []
for p in pts:
sh = base.copy()
sh.translate(p)
fsh.append(sh)
obj.Shape = Part.makeCompound(fsh)
else:
obj.Shape = base
if not fcgeo.isNull(pl): obj.Placement = pl
class _ViewProviderStructure(ArchComponent.ViewProviderComponent):

View File

@ -86,36 +86,37 @@ def readOpenShell(filename):
import Mesh
getIfcOpenShell()
if IfcOpenShell:
IfcOpenShell.Init(filename)
while True:
obj = IfcOpenShell.Get()
print "parsing ",obj.guid,": ",obj.name," of type ",obj.type
meshdata = []
n = obj.name
if not n: n = "Unnamed"
f = obj.mesh.faces
v = obj.mesh.verts
m = obj.matrix
print "verts: ",len(v)," faces: ",len(f)
mat = FreeCAD.Matrix(m[0], m[1], m[2], 0,
m[3], m[4], m[5], 0,
m[6], m[7], m[8], 0,
m[9], m[10], m[11], 1)
for i in range(0, len(f), 3):
print "face ",f[i],f[i+1],f[i+2]
face = []
print "i:",i
for j in range(3):
vi = f[i+j]*3
print "vi:",vi
face.append([v[vi],v[vi+1],v[vi+2]])
meshdata.append(face)
newmesh = Mesh.Mesh(meshdata)
mobj = FreeCAD.ActiveDocument.addObject("Mesh::Feature",n)
mobj.Mesh = newmesh
mobj.Placement = FreeCAD.Placement(mat)
if not IfcOpenShell.Next():
break
if IfcOpenShell.Init(filename):
while True:
obj = IfcOpenShell.Get()
print "parsing ",obj.guid,": ",obj.name," of type ",obj.type
meshdata = []
n = obj.name
if not n: n = "Unnamed"
f = obj.mesh.faces
v = obj.mesh.verts
m = obj.matrix
print "verts: ",len(v)," faces: ",len(f)
mat = FreeCAD.Matrix(m[0], m[3], m[6], m[9],
m[1], m[4], m[7], m[10],
m[2], m[5], m[8], m[11],
0, 0, 0, 1)
for i in range(0, len(f), 3):
print "face ",f[i],f[i+1],f[i+2]
face = []
print "i:",i
for j in range(3):
vi = f[i+j]*3
print "vi:",vi
face.append([v[vi],v[vi+1],v[vi+2]])
meshdata.append(face)
newmesh = Mesh.Mesh(meshdata)
mobj = FreeCAD.ActiveDocument.addObject("Mesh::Feature",n)
mobj.Mesh = newmesh
mobj.Placement = FreeCAD.Placement(mat)
if not IfcOpenShell.Next():
break
IfcOpenShell.CleanUp()
return None
def read(filename):

View File

@ -283,21 +283,40 @@ def select(objs=None):
FreeCADGui.Selection.addSelection(obj)
def makeCircle(radius, placement=None, face=True, startangle=None, endangle=None, support=None):
'''makeCircle(radius,[placement,face,startangle,endangle]): Creates a circle
object with given radius. If placement is given, it is
'''makeCircle(radius,[placement,face,startangle,endangle])
or makeCircle(edge,[face]):
Creates a circle object with given radius. If placement is given, it is
used. If face is False, the circle is shown as a
wireframe, otherwise as a face. If startangle AND endangle are given
(in degrees), they are used and the object appears as an arc.'''
(in degrees), they are used and the object appears as an arc. If an edge
is passed, its Curve must be a Part.Circle'''
import Part
if placement: typecheck([(placement,FreeCAD.Placement)], "makeCircle")
obj = FreeCAD.ActiveDocument.addObject("Part::Part2DObjectPython","Circle")
_Circle(obj)
_ViewProviderDraft(obj.ViewObject)
obj.Radius = radius
if isinstance(radius,Part.Edge):
edge = radius
if isinstance(edge.Curve,Part.Circle):
obj.Radius = edge.Curve.Radius
placement = FreeCAD.Placement(edge.Placement)
delta = edge.Curve.Center.sub(placement.Base)
placement.move(delta)
if len(edge.Vertexes) > 1:
ref = placement.multVec(FreeCAD.Vector(1,0,0))
v1 = (edge.Vertexes[0].Point).sub(edge.Curve.Center)
v2 = (edge.Vertexes[-1].Point).sub(edge.Curve.Center)
a1 = -math.degrees(fcvec.angle(v1,ref))
a2 = -math.degrees(fcvec.angle(v2,ref))
obj.FirstAngle = a1
obj.LastAngle = a2
else:
obj.Radius = radius
if (startangle != None) and (endangle != None):
if startangle == -0: startangle = 0
obj.FirstAngle = startangle
obj.LastAngle = endangle
if not face: obj.ViewObject.DisplayMode = "Wireframe"
if (startangle != None) and (endangle != None):
if startangle == -0: startangle = 0
obj.FirstAngle = startangle
obj.LastAngle = endangle
obj.Support = support
if placement: obj.Placement = placement
formatObject(obj)
@ -517,13 +536,13 @@ def makeCopy(obj):
_Block(newobj)
_ViewProviderDraftPart(newobj.ViewObject)
elif getType(obj) == "Structure":
import Structure
Structure._Structure(newobj)
Structure._ViewProviderStructure(newobj.ViewObject)
import Arch
Arch._Structure(newobj)
Arch._ViewProviderStructure(newobj.ViewObject)
elif getType(obj) == "Wall":
import Wall
Wall._Wall(newobj)
Wall._ViewProviderWall(newobj.ViewObject)
import Arch
Arch._Wall(newobj)
Arch._ViewProviderWall(newobj.ViewObject)
elif obj.isDerivedFrom("Part::Feature"):
newobj.Shape = obj.Shape
else:
@ -937,6 +956,7 @@ def draftify(objectslist,makeblock=False):
(objectslist can also be a single object) into a Draft parametric
wire. If makeblock is True, multiple objects will be grouped in a block'''
from draftlibs import fcgeo
import Part
if not isinstance(objectslist,list):
objectslist = [objectslist]
newobjlist = []
@ -944,8 +964,11 @@ def draftify(objectslist,makeblock=False):
if obj.isDerivedFrom('Part::Feature'):
for w in obj.Shape.Wires:
if fcgeo.hasCurves(w):
nobj = FreeCAD.ActiveDocument.addObject("Part::Feature",name)
nobj.Shape = w
if (len(w.Edges) == 1) and isinstance(w.Edges[0].Curve,Part.Circle):
nobj = makeCircle(w.Edges[0])
else:
nobj = FreeCAD.ActiveDocument.addObject("Part::Feature",obj.Name)
nobj.Shape = w
else:
nobj = makeWire(w)
if obj.Shape.Faces:
@ -1222,6 +1245,7 @@ def makeSketch(objectslist,autoconstraints=False,addTo=None,name="Sketch"):
nobj = addTo
else:
nobj = FreeCAD.ActiveDocument.addObject("Sketcher::SketchObject",name)
nobj.ViewObject.Autoconstraints = False
for obj in objectslist:
ok = False
tp = getType(obj)
@ -1274,7 +1298,9 @@ def makeSketch(objectslist,autoconstraints=False,addTo=None,name="Sketch"):
if fcgeo.hasOnlyWires(obj.Shape):
for w in obj.Shape.Wires:
for edge in fcgeo.sortEdges(w.Edges):
nobj.addGeometry(fcgeo.geom(edge))
g = fcgeo.geom(edge)
if g:
nobj.addGeometry(g)
if autoconstraints:
last = nobj.GeometryCount
segs = range(last-len(w.Edges),last-1)
@ -1429,7 +1455,7 @@ class _ViewProviderDimension:
obj.addProperty("App::PropertyLength","LineWidth","Base","Line width")
obj.addProperty("App::PropertyColor","LineColor","Base","Line color")
obj.addProperty("App::PropertyLength","ExtLines","Base","Ext lines")
obj.addProperty("App::PropertyVector","Position","Base","The position of the text. Leave (0,0,0) for automatic position")
obj.addProperty("App::PropertyVector","TextPosition","Base","The position of the text. Leave (0,0,0) for automatic position")
obj.addProperty("App::PropertyString","Override","Base","Text override. Use 'dim' to insert the dimension length")
obj.Proxy = self
obj.FontSize=getParam("textheight")
@ -1476,10 +1502,10 @@ class _ViewProviderDimension:
if hasattr(obj.ViewObject,"DisplayMode"):
if obj.ViewObject.DisplayMode == "3D":
offset = fcvec.neg(offset)
if obj.ViewObject.Position == Vector(0,0,0):
if obj.ViewObject.TextPosition == Vector(0,0,0):
tbase = midpoint.add(offset)
else:
tbase = obj.ViewObject.Position
tbase = obj.ViewObject.TextPosition
rot = FreeCAD.Placement(fcvec.getPlaneRotation(u,v,norm)).Rotation.Q
return p1,p2,p3,p4,tbase,norm,rot
@ -1719,7 +1745,7 @@ class _ViewProviderAngularDimension:
obj.addProperty("App::PropertyString","FontName","Base","Font name")
obj.addProperty("App::PropertyLength","LineWidth","Base","Line width")
obj.addProperty("App::PropertyColor","LineColor","Base","Line color")
obj.addProperty("App::PropertyVector","Position","Base","The position of the text. Leave (0,0,0) for automatic position")
obj.addProperty("App::PropertyVector","TextPosition","Base","The position of the text. Leave (0,0,0) for automatic position")
obj.addProperty("App::PropertyString","Override","Base","Text override. Use 'dim' to insert the dimension length")
obj.Proxy = self
obj.FontSize=getParam("textheight")

View File

@ -152,7 +152,7 @@ class Snapper:
if self.extLine:
self.extLine.off()
point = FreeCADGui.ActiveDocument.ActiveView.getPoint(screenpos[0],screenpos[1])
point = self.getApparentPoint(screenpos[0],screenpos[1])
# check if we snapped to something
info = FreeCADGui.ActiveDocument.ActiveView.getObjectInfo((screenpos[0],screenpos[1]))
@ -259,6 +259,12 @@ class Snapper:
# return the final point
return cstr(winner[2])
def getApparentPoint(self,x,y):
"returns a 3D point, projected on the current working plane"
pt = FreeCADGui.ActiveDocument.ActiveView.getPoint(x,y)
dv = FreeCADGui.ActiveDocument.ActiveView.getViewDirection()
return FreeCAD.DraftWorkingPlane.projectPoint(pt,dv)
def snapToExtensions(self,point,last,constrain):
"returns a point snapped to extension or parallel line to last object, if any"
@ -515,7 +521,8 @@ class Snapper:
delta = point.sub(self.basepoint)
# setting constraint axis
self.affinity = FreeCAD.DraftWorkingPlane.getClosestAxis(delta)
if not self.affinity:
self.affinity = FreeCAD.DraftWorkingPlane.getClosestAxis(delta)
if isinstance(axis,FreeCAD.Vector):
self.constraintAxis = axis
elif axis == "x":

View File

@ -455,9 +455,9 @@ class Line(Creator):
if len(edges) > 1:
edges.pop()
newshape = Part.Wire(edges)
self.obj.Shape = newshape
else:
newshape = Part.Shape()
self.obj.Shape = newshape
self.obj.ViewObject.hide()
# DNC: report on removal
msg(translate("draft", "Last point has been removed\n"))
@ -2114,7 +2114,8 @@ class Offset(Modifier):
v2 = fcgeo.getTangent(self.shape.Edges[dist[1]],point)
a = -fcvec.angle(v1,v2)
self.dvec = fcvec.rotate(d,a,plane.axis)
self.ghost.update(fcgeo.offsetWire(self.shape,self.dvec,occ=self.ui.occOffset.isChecked()))
occmode = self.ui.occOffset.isChecked()
self.ghost.update(fcgeo.offsetWire(self.shape,self.dvec,occ=occmode),forceclosed=occmode)
elif self.mode == "Circle":
self.dvec = point.sub(self.center).Length
self.ghost.setRadius(self.dvec)
@ -3080,8 +3081,9 @@ class Edit(Modifier):
if self.obj:
self.obj = self.obj[0]
# store selectable state of the object
self.selectstate = self.obj.ViewObject.Selectable
self.obj.ViewObject.Selectable = False
if hasattr(self.obj.ViewObject,"Selectable"):
self.selectstate = self.obj.ViewObject.Selectable
self.obj.ViewObject.Selectable = False
if not Draft.getType(self.obj) in ["Wire","BSpline"]:
self.ui.setEditButtons(False)
else:
@ -3148,7 +3150,8 @@ class Edit(Modifier):
t.finalize()
if self.constraintrack:
self.constraintrack.finalize()
self.obj.ViewObject.Selectable = self.selectstate
if hasattr(self.obj.ViewObject,"Selectable"):
self.obj.ViewObject.Selectable = self.selectstate
Modifier.finish(self)
plane.restore()
self.running = False
@ -3188,13 +3191,15 @@ class Edit(Modifier):
self.ui.isRelative.show()
self.editing = int(snapped['Component'][8:])
self.trackers[self.editing].off()
self.obj.ViewObject.Selectable = False
if hasattr(self.obj.ViewObject,"Selectable"):
self.obj.ViewObject.Selectable = False
if "Points" in self.obj.PropertiesList:
self.node.append(self.obj.Points[self.editing])
else:
print "finishing edit"
self.trackers[self.editing].on()
self.obj.ViewObject.Selectable = True
if hasattr(self.obj.ViewObject,"Selectable"):
self.obj.ViewObject.Selectable = True
self.numericInput(self.trackers[self.editing].get())
def update(self,v):
@ -3540,6 +3545,9 @@ class Draft2Sketch():
allDraft = False
elif obj.isDerivedFrom("Part::Part2DObjectPython"):
allSketches = False
else:
allDraft = False
allSketches = False
if not sel:
return
elif allDraft:
@ -3554,9 +3562,12 @@ class Draft2Sketch():
FreeCAD.ActiveDocument.openTransaction("Convert")
for obj in sel:
if obj.isDerivedFrom("Sketcher::SketchObject"):
Draft.makeSketch(sel,autoconstraints=True)
Draft.draftify(obj)
elif obj.isDerivedFrom("Part::Part2DObjectPython"):
Draft.draftify(sel,makeblock=True)
Draft.makeSketch(obj,autoconstraints=True)
elif obj.isDerivedFrom("Part::Feature"):
if len(obj.Shape.Wires) == 1:
Draft.makeSketch(obj,autoconstraints=False)
FreeCAD.ActiveDocument.commitTransaction()

View File

@ -505,16 +505,16 @@ class wireTracker(Tracker):
self.update(wire)
Tracker.__init__(self,children=[self.coords,self.line])
def update(self,wire):
def update(self,wire,forceclosed=False):
if wire:
if self.closed:
if self.closed or forceclosed:
self.line.numVertices.setValue(len(wire.Vertexes)+1)
else:
self.line.numVertices.setValue(len(wire.Vertexes))
for i in range(len(wire.Vertexes)):
p=wire.Vertexes[i].Point
self.coords.point.set1Value(i,[p.x,p.y,p.z])
if self.closed:
if self.closed or forceclosed:
t = len(wire.Vertexes)
p = wire.Vertexes[0].Point
self.coords.point.set1Value(t,[p.x,p.y,p.z])

View File

@ -361,14 +361,17 @@ def geom(edge):
return edge.Curve
elif isinstance(edge.Curve,Part.Circle):
if len(edge.Vertexes) == 1:
return edge.Curve
return Part.Circle(edge.Curve.Center,edge.Curve.Axis,edge.Curve.Radius)
else:
ref = edge.Placement.multVec(Vector(1,0,0))
v1 = edge.Vertexes[0].Point
v2 = edge.Vertexes[-1].Point
c = edge.Curve.Center
a1 = -fcvec.angle(v1.sub(c))
a2 = -fcvec.angle(v2.sub(c))
return Part.ArcOfCircle(edge.Curve,a1,a2)
cu = Part.Circle(edge.Curve.Center,edge.Curve.Axis,edge.Curve.Radius)
a1 = -fcvec.angle(v1.sub(c),ref)
a2 = -fcvec.angle(v2.sub(c),ref)
p= Part.ArcOfCircle(cu,a1,a2)
return p
else:
return edge.Curve
@ -764,12 +767,20 @@ def connect(edges,closed=False):
next = None
if prev:
# print "debug: fcgeo.connect prev : ",prev.Vertexes[0].Point,prev.Vertexes[-1].Point
v1 = findIntersection(curr,prev,True,True)[0]
i = findIntersection(curr,prev,True,True)
if i:
v1 = i[0]
else:
v1 = curr.Vertexes[0].Point
else:
v1 = curr.Vertexes[0].Point
if next:
# print "debug: fcgeo.connect next : ",next.Vertexes[0].Point,next.Vertexes[-1].Point
v2 = findIntersection(curr,next,True,True)[0]
i = findIntersection(curr,next,True,True)
if i:
v2 = i[0]
else:
v2 = curr.Vertexes[-1].Point
else:
v2 = curr.Vertexes[-1].Point
if isinstance(curr.Curve,Part.Line):
@ -778,7 +789,10 @@ def connect(edges,closed=False):
elif isinstance(curr.Curve,Part.Circle):
if v1 != v2:
nedges.append(Part.Arc(v1,findMidPoint(curr),v2))
return Part.Wire(nedges)
try:
return Part.Wire(nedges)
except:
return None
def findDistance(point,edge,strict=False):
'''