Merge branch 'master' of https://github.com/FreeCAD/FreeCAD into toolbit-gui
This commit is contained in:
@@ -856,6 +856,13 @@ void InventorBuilder::addCylinder(float radius, float height)
|
||||
<< Base::blanks(indent) << "}\n";
|
||||
}
|
||||
|
||||
void InventorBuilder::addSphere(float radius)
|
||||
{
|
||||
result << Base::blanks(indent) << "Sphere {\n"
|
||||
<< Base::blanks(indent) << " radius " << radius << "\n"
|
||||
<< Base::blanks(indent) << "}\n";
|
||||
}
|
||||
|
||||
void InventorBuilder::addBoundingBox(const Vector3f& pt1, const Vector3f& pt2, short lineWidth,
|
||||
float color_r,float color_g,float color_b)
|
||||
{
|
||||
|
||||
@@ -301,6 +301,7 @@ public:
|
||||
int numUControlPoints, int numVControlPoints,
|
||||
const std::vector<float>& uKnots, const std::vector<float>& vKnots);
|
||||
void addCylinder(float radius, float height);
|
||||
void addSphere(float radius);
|
||||
//@}
|
||||
|
||||
/** @name Bounding Box handling */
|
||||
|
||||
@@ -258,7 +258,9 @@ public:
|
||||
|
||||
static PyObject* sRunCommand (PyObject *self,PyObject *args);
|
||||
static PyObject* sAddCommand (PyObject *self,PyObject *args);
|
||||
static PyObject* sGetCommandInfo (PyObject *self,PyObject *args);
|
||||
static PyObject* sListCommands (PyObject *self,PyObject *args);
|
||||
static PyObject* sGetCommandShortcut (PyObject *self,PyObject *args);
|
||||
static PyObject* sIsCommandActive (PyObject *self,PyObject *args);
|
||||
static PyObject* sUpdateCommands (PyObject *self,PyObject *args);
|
||||
|
||||
|
||||
@@ -144,6 +144,12 @@ PyMethodDef Application::Methods[] = {
|
||||
{"listCommands", (PyCFunction) Application::sListCommands, METH_VARARGS,
|
||||
"listCommands() -> list of strings\n\n"
|
||||
"Returns a list of all commands known to FreeCAD."},
|
||||
{"getCommandInfo", (PyCFunction) Application::sGetCommandInfo, METH_VARARGS,
|
||||
"getCommandInfo(string) -> list of strings\n\n"
|
||||
"Usage: menuText,tooltipText,whatsThisText,statustipText,pixmapText,shortcutText = getCommandInfo(string)"},
|
||||
{"getCommandShortcut", (PyCFunction) Application::sGetCommandShortcut, METH_VARARGS,
|
||||
"getCommandShortcut(string) -> string\n\n"
|
||||
"Returns string representing shortcut key accelerator for command."},
|
||||
{"updateCommands", (PyCFunction) Application::sUpdateCommands, METH_VARARGS,
|
||||
"updateCommands\n\n"
|
||||
"Update all command active status"},
|
||||
@@ -1273,6 +1279,73 @@ PyObject* Application::sUpdateCommands(PyObject * /*self*/, PyObject *args)
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
PyObject* Application::sGetCommandShortcut(PyObject * /*self*/, PyObject *args)
|
||||
{
|
||||
char* pName;
|
||||
if (!PyArg_ParseTuple(args, "s", &pName))
|
||||
return NULL;
|
||||
|
||||
Command* cmd = Application::Instance->commandManager().getCommandByName(pName);
|
||||
if (cmd) {
|
||||
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
PyObject* str = PyUnicode_FromString(cmd->getAccel() ? cmd->getAccel() : "");
|
||||
#else
|
||||
PyObject* str = PyString_FromString(cmd->getAccel() ? cmd->getAccel() : "");
|
||||
#endif
|
||||
return str;
|
||||
}
|
||||
else {
|
||||
PyErr_Format(Base::BaseExceptionFreeCADError, "No such command '%s'", pName);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
PyObject* Application::sGetCommandInfo(PyObject * /*self*/, PyObject *args)
|
||||
{
|
||||
char* pName;
|
||||
if (!PyArg_ParseTuple(args, "s", &pName))
|
||||
return NULL;
|
||||
|
||||
Command* cmd = Application::Instance->commandManager().getCommandByName(pName);
|
||||
if (cmd) {
|
||||
PyObject* pyList = PyList_New(6);
|
||||
const char* menuTxt = cmd->getMenuText();
|
||||
const char* tooltipTxt = cmd->getToolTipText();
|
||||
const char* whatsThisTxt = cmd->getWhatsThis();
|
||||
const char* statustipTxt = cmd->getStatusTip();
|
||||
const char* pixMapTxt = cmd->getPixmap();
|
||||
const char* shortcutTxt = cmd->getAccel();
|
||||
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
PyObject* strMenuTxt = PyUnicode_FromString(menuTxt ? menuTxt : "");
|
||||
PyObject* strTooltipTxt = PyUnicode_FromString(tooltipTxt ? tooltipTxt : "");
|
||||
PyObject* strWhatsThisTxt = PyUnicode_FromString(whatsThisTxt ? whatsThisTxt : "");
|
||||
PyObject* strStatustipTxt = PyUnicode_FromString(statustipTxt ? statustipTxt : "");
|
||||
PyObject* strPixMapTxt = PyUnicode_FromString(pixMapTxt ? pixMapTxt : "");
|
||||
PyObject* strShortcutTxt = PyUnicode_FromString(shortcutTxt ? shortcutTxt : "");
|
||||
#else
|
||||
PyObject* strMenuTxt = PyString_FromString(menuTxt ? menuTxt : "");
|
||||
PyObject* strTooltipTxt = PyString_FromString(tooltipTxt ? tooltipTxt : "");
|
||||
PyObject* strWhatsThisTxt = PyString_FromString(whatsThisTxt ? whatsThisTxt : "");
|
||||
PyObject* strStatustipTxt = PyString_FromString(statustipTxt ? statustipTxt : "");
|
||||
PyObject* strPixMapTxt = PyString_FromString(pixMapTxt ? pixMapTxt : "");
|
||||
PyObject* strShortcutTxt = PyString_FromString(shortcutTxt ? shortcutTxt : "");
|
||||
#endif
|
||||
PyList_SetItem(pyList, 0, strMenuTxt);
|
||||
PyList_SetItem(pyList, 1, strTooltipTxt);
|
||||
PyList_SetItem(pyList, 2, strWhatsThisTxt);
|
||||
PyList_SetItem(pyList, 3, strStatustipTxt);
|
||||
PyList_SetItem(pyList, 4, strPixMapTxt);
|
||||
PyList_SetItem(pyList, 5, strShortcutTxt);
|
||||
return pyList;
|
||||
}
|
||||
else {
|
||||
PyErr_Format(Base::BaseExceptionFreeCADError, "No such command '%s'", pName);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
PyObject* Application::sListCommands(PyObject * /*self*/, PyObject *args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args, ""))
|
||||
|
||||
+38
-12
@@ -190,15 +190,17 @@ class _ArchPipe(ArchComponent.Component):
|
||||
|
||||
pl = obj.PropertiesList
|
||||
if not "Diameter" in pl:
|
||||
obj.addProperty("App::PropertyLength", "Diameter", "Pipe", QT_TRANSLATE_NOOP("App::Property","The diameter of this pipe, if not based on a profile"))
|
||||
obj.addProperty("App::PropertyLength", "Diameter", "Pipe", QT_TRANSLATE_NOOP("App::Property","The diameter of this pipe, if not based on a profile"))
|
||||
if not "Length" in pl:
|
||||
obj.addProperty("App::PropertyLength", "Length", "Pipe", QT_TRANSLATE_NOOP("App::Property","The length of this pipe, if not based on an edge"))
|
||||
obj.addProperty("App::PropertyLength", "Length", "Pipe", QT_TRANSLATE_NOOP("App::Property","The length of this pipe, if not based on an edge"))
|
||||
if not "Profile" in pl:
|
||||
obj.addProperty("App::PropertyLink", "Profile", "Pipe", QT_TRANSLATE_NOOP("App::Property","An optional closed profile to base this pipe on"))
|
||||
obj.addProperty("App::PropertyLink", "Profile", "Pipe", QT_TRANSLATE_NOOP("App::Property","An optional closed profile to base this pipe on"))
|
||||
if not "OffsetStart" in pl:
|
||||
obj.addProperty("App::PropertyLength", "OffsetStart", "Pipe", QT_TRANSLATE_NOOP("App::Property","Offset from the start point"))
|
||||
obj.addProperty("App::PropertyLength", "OffsetStart", "Pipe", QT_TRANSLATE_NOOP("App::Property","Offset from the start point"))
|
||||
if not "OffsetEnd" in pl:
|
||||
obj.addProperty("App::PropertyLength", "OffsetEnd", "Pipe", QT_TRANSLATE_NOOP("App::Property","Offset from the end point"))
|
||||
obj.addProperty("App::PropertyLength", "OffsetEnd", "Pipe", QT_TRANSLATE_NOOP("App::Property","Offset from the end point"))
|
||||
if not "WallThickness" in pl:
|
||||
obj.addProperty("App::PropertyLength", "WallThickness","Pipe", QT_TRANSLATE_NOOP("App::Property","The wall thickness of this pipe, if not based on a profile"))
|
||||
self.Type = "Pipe"
|
||||
|
||||
def onDocumentRestored(self,obj):
|
||||
@@ -231,7 +233,11 @@ class _ArchPipe(ArchComponent.Component):
|
||||
FreeCAD.Console.PrintError(translate("Arch","Unable to build the profile")+"\n")
|
||||
return
|
||||
# move and rotate the profile to the first point
|
||||
delta = w.Vertexes[0].Point-p.CenterOfMass
|
||||
if hasattr(p,"CenterOfMass"):
|
||||
c = p.CenterOfMass
|
||||
else:
|
||||
c = p.BoundBox.Center
|
||||
delta = w.Vertexes[0].Point-c
|
||||
p.translate(delta)
|
||||
import Draft
|
||||
if Draft.getType(obj.Base) == "BezCurve":
|
||||
@@ -240,12 +246,30 @@ class _ArchPipe(ArchComponent.Component):
|
||||
v1 = w.Vertexes[1].Point-w.Vertexes[0].Point
|
||||
v2 = DraftGeomUtils.getNormal(p)
|
||||
rot = FreeCAD.Rotation(v2,v1)
|
||||
p.rotate(p.CenterOfMass,rot.Axis,math.degrees(rot.Angle))
|
||||
p.rotate(c,rot.Axis,math.degrees(rot.Angle))
|
||||
shapes = []
|
||||
try:
|
||||
sh = w.makePipeShell([p],True,False,2)
|
||||
if p.Faces:
|
||||
for f in p.Faces:
|
||||
sh = w.makePipeShell([f.OuterWire],True,False,2)
|
||||
for shw in f.Wires:
|
||||
if shw.hashCode() != f.OuterWire.hashCode():
|
||||
sh2 = w.makePipeShell([shw],True,False,2)
|
||||
sh = sh.cut(sh2)
|
||||
shapes.append(sh)
|
||||
elif p.Wires:
|
||||
for pw in p.Wires:
|
||||
sh = w.makePipeShell([pw],True,False,2)
|
||||
shapes.append(sh)
|
||||
except:
|
||||
FreeCAD.Console.PrintError(translate("Arch","Unable to build the pipe")+"\n")
|
||||
else:
|
||||
if len(shapes) == 0:
|
||||
return
|
||||
elif len(shapes) == 1:
|
||||
sh = shapes[0]
|
||||
else:
|
||||
sh = Part.makeCompound(shapes)
|
||||
obj.Shape = sh
|
||||
if obj.Base:
|
||||
obj.Length = w.Length
|
||||
@@ -279,17 +303,19 @@ class _ArchPipe(ArchComponent.Component):
|
||||
if not obj.Profile.getLinkedObject().isDerivedFrom("Part::Part2DObject"):
|
||||
FreeCAD.Console.PrintError(translate("Arch","The profile is not a 2D Part")+"\n")
|
||||
return
|
||||
if len(obj.Profile.Shape.Wires) != 1:
|
||||
FreeCAD.Console.PrintError(translate("Arch","Too many wires in the profile")+"\n")
|
||||
return
|
||||
if not obj.Profile.Shape.Wires[0].isClosed():
|
||||
FreeCAD.Console.PrintError(translate("Arch","The profile is not closed")+"\n")
|
||||
return
|
||||
p = obj.Profile.Shape.Wires[0]
|
||||
p = obj.Profile.Shape
|
||||
else:
|
||||
if obj.Diameter.Value == 0:
|
||||
return
|
||||
p = Part.Wire([Part.Circle(FreeCAD.Vector(0,0,0),FreeCAD.Vector(0,0,1),obj.Diameter.Value/2).toShape()])
|
||||
if obj.WallThickness.Value and (obj.WallThickness.Value < obj.Diameter.Value/2):
|
||||
p2 = Part.Wire([Part.Circle(FreeCAD.Vector(0,0,0),FreeCAD.Vector(0,0,1),(obj.Diameter.Value/2-obj.WallThickness.Value)).toShape()])
|
||||
p = Part.Face(p)
|
||||
p2 = Part.Face(p2)
|
||||
p = p.cut(p2)
|
||||
return p
|
||||
|
||||
|
||||
|
||||
@@ -301,14 +301,40 @@ class _Rebar(ArchComponent.Component):
|
||||
if self.clone(obj):
|
||||
return
|
||||
if not obj.Base:
|
||||
FreeCAD.Console.PrintError(
|
||||
"No Base, return without a rebar shape for {}.\n"
|
||||
.format(obj.Name)
|
||||
)
|
||||
return
|
||||
if not obj.Base.Shape:
|
||||
FreeCAD.Console.PrintError(
|
||||
"No Shape in Base, return without a rebar shape for {}.\n"
|
||||
.format(obj.Name)
|
||||
)
|
||||
return
|
||||
if not obj.Base.Shape.Wires:
|
||||
if obj.Base.Shape.Faces:
|
||||
FreeCAD.Console.PrintError(
|
||||
"Faces in Shape of Base, return without a rebar shape for {}.\n"
|
||||
.format(obj.Name)
|
||||
)
|
||||
return
|
||||
if not obj.Base.Shape.Edges:
|
||||
FreeCAD.Console.PrintError(
|
||||
"No Edges in Shape of Base, return without a rebar shape for {}.\n"
|
||||
.format(obj.Name)
|
||||
)
|
||||
return
|
||||
if not obj.Diameter.Value:
|
||||
FreeCAD.Console.PrintError(
|
||||
"No Diameter Value, return without a rebar shape for {}.\n"
|
||||
.format(obj.Name)
|
||||
)
|
||||
return
|
||||
if not obj.Amount:
|
||||
FreeCAD.Console.PrintError(
|
||||
"No Amount, return without a rebar shape for {}.\n"
|
||||
.format(obj.Name)
|
||||
)
|
||||
return
|
||||
father = obj.Host
|
||||
fathershape = None
|
||||
@@ -322,13 +348,22 @@ class _Rebar(ArchComponent.Component):
|
||||
if hasattr(father,'Shape'):
|
||||
fathershape = father.Shape
|
||||
|
||||
wire = obj.Base.Shape.Wires[0]
|
||||
import Part
|
||||
# corner cases:
|
||||
# compound from more Wires
|
||||
# compound without Wires but with multiple Edges
|
||||
# Does they make sense? If yes handle them.
|
||||
# Does it makes sense to handle Shapes with Faces or even Solids?
|
||||
if not obj.Base.Shape.Wires and len(obj.Base.Shape.Edges) == 1:
|
||||
wire = Part.Wire(obj.Base.Shape.Edges[0])
|
||||
else:
|
||||
wire = obj.Base.Shape.Wires[0]
|
||||
if hasattr(obj,"Rounding"):
|
||||
#print(obj.Rounding)
|
||||
if obj.Rounding:
|
||||
radius = obj.Rounding * obj.Diameter.Value
|
||||
import DraftGeomUtils
|
||||
wire = DraftGeomUtils.filletWire(wire,radius)
|
||||
from DraftGeomUtils import filletWire
|
||||
wire = filletWire(wire,radius)
|
||||
bpoint, bvec = self.getBaseAndAxis(wire)
|
||||
if not bpoint:
|
||||
return
|
||||
@@ -362,7 +397,6 @@ class _Rebar(ArchComponent.Component):
|
||||
if length:
|
||||
obj.Length = length
|
||||
pl = obj.Placement
|
||||
import Part
|
||||
circle = Part.makeCircle(obj.Diameter.Value/2,bpoint,bvec)
|
||||
circle = Part.Wire(circle)
|
||||
try:
|
||||
|
||||
@@ -784,6 +784,15 @@ class _CommandWindow:
|
||||
self.librarypresets.append([wtype+" - "+subtype+" - "+os.path.splitext(subfile)[0],os.path.join(subdir,subfile)])
|
||||
else:
|
||||
librarypath = None
|
||||
# check for existing presets
|
||||
presetdir = os.path.join(FreeCAD.getUserAppDataDir(),"Arch")
|
||||
for tp in ["Windows","Doors"]:
|
||||
wdir = os.path.join(presetdir,tp)
|
||||
if os.path.exists(wdir):
|
||||
for wfile in os.listdir(wdir):
|
||||
if wfile.lower().endswith(".fcstd"):
|
||||
self.librarypresets.append([tp[:-1]+" - "+wfile[:-6],wfile])
|
||||
|
||||
|
||||
# presets box
|
||||
labelp = QtGui.QLabel(translate("Arch","Preset"))
|
||||
|
||||
@@ -77,12 +77,12 @@ void AssemblyExport initAssembly()
|
||||
// call PyType_Ready, otherwise we run into a segmentation fault, later on.
|
||||
// This function is responsible for adding inherited slots from a type's base class.
|
||||
|
||||
// Item hirachy
|
||||
// Item hierarchy
|
||||
Assembly::Item ::init();
|
||||
Assembly::Product ::init();
|
||||
Assembly::ProductRef ::init();
|
||||
|
||||
// constraint hirachy
|
||||
// constraint hierarchy
|
||||
Assembly::Constraint ::init();
|
||||
Assembly::ConstraintGroup ::init();
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ SET(Draft_SRCS_base
|
||||
WorkingPlane.py
|
||||
getSVG.py
|
||||
TestDraft.py
|
||||
TestDraftGui.py
|
||||
)
|
||||
|
||||
SET(Draft_import
|
||||
@@ -79,6 +80,7 @@ SET(Draft_GUI_tools
|
||||
draftguitools/gui_circulararray.py
|
||||
draftguitools/gui_orthoarray.py
|
||||
draftguitools/gui_polararray.py
|
||||
draftguitools/gui_planeproxy.py
|
||||
draftguitools/gui_selectplane.py
|
||||
draftguitools/gui_arrays.py
|
||||
draftguitools/gui_snaps.py
|
||||
@@ -94,6 +96,7 @@ SET(Draft_task_panels
|
||||
drafttaskpanels/task_orthoarray.py
|
||||
drafttaskpanels/task_polararray.py
|
||||
drafttaskpanels/task_scale.py
|
||||
drafttaskpanels/task_selectplane.py
|
||||
drafttaskpanels/task_shapestring.py
|
||||
drafttaskpanels/README.md
|
||||
)
|
||||
|
||||
+116
-116
@@ -1,174 +1,173 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#***************************************************************************
|
||||
#* Copyright (c) 2009, 2010 Yorik van Havre <[email protected]> *
|
||||
#* Copyright (c) 2009, 2010 Ken Cline <[email protected]> *
|
||||
#* *
|
||||
#* This program is free software; you can redistribute it and/or modify *
|
||||
#* it under the terms of the GNU Lesser General Public License (LGPL) *
|
||||
#* as published by the Free Software Foundation; either version 2 of *
|
||||
#* the License, or (at your option) any later version. *
|
||||
#* for detail see the LICENCE text file. *
|
||||
#* *
|
||||
#* This program is distributed in the hope that it will be useful, *
|
||||
#* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
#* GNU Library General Public License for more details. *
|
||||
#* *
|
||||
#* You should have received a copy of the GNU Library General Public *
|
||||
#* License along with this program; if not, write to the Free Software *
|
||||
#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
||||
#* USA *
|
||||
#* *
|
||||
#***************************************************************************
|
||||
|
||||
#from __future__ import division
|
||||
|
||||
__title__="FreeCAD Draft Workbench"
|
||||
__author__ = "Yorik van Havre, Werner Mayer, Martin Burbaum, Ken Cline, Dmitry Chigrin, Daniel Falck"
|
||||
__url__ = "https://www.freecadweb.org"
|
||||
# ***************************************************************************
|
||||
# * Copyright (c) 2009, 2010 Yorik van Havre <[email protected]> *
|
||||
# * Copyright (c) 2009, 2010 Ken Cline <[email protected]> *
|
||||
# * *
|
||||
# * This program is free software; you can redistribute it and/or modify *
|
||||
# * it under the terms of the GNU Lesser General Public License (LGPL) *
|
||||
# * as published by the Free Software Foundation; either version 2 of *
|
||||
# * the License, or (at your option) any later version. *
|
||||
# * for detail see the LICENCE text file. *
|
||||
# * *
|
||||
# * This program is distributed in the hope that it will be useful, *
|
||||
# * but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
# * GNU Library General Public License for more details. *
|
||||
# * *
|
||||
# * You should have received a copy of the GNU Library General Public *
|
||||
# * License along with this program; if not, write to the Free Software *
|
||||
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
||||
# * USA *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
"""Provide the Draft Workbench public programming interface.
|
||||
|
||||
The Draft module offers tools to create and manipulate 2D objects.
|
||||
The functions in this file must be usable without requiring the
|
||||
graphical user interface.
|
||||
These functions can be used as the backend for the graphical commands
|
||||
defined in `DraftTools.py`.
|
||||
"""
|
||||
## \addtogroup DRAFT
|
||||
# \brief Create and manipulate basic 2D objects
|
||||
#
|
||||
# This module offers a range of tools to create and manipulate basic 2D objects
|
||||
# This module offers tools to create and manipulate basic 2D objects
|
||||
#
|
||||
# The module allows to create 2D geometric objects such as line, rectangle, circle,
|
||||
# etc, modify these objects by moving, scaling or rotating them, and offers a couple of
|
||||
# other utilities to manipulate further these objects, such as decompose them (downgrade)
|
||||
# into smaller elements.
|
||||
# The module allows to create 2D geometric objects such as line, rectangle,
|
||||
# circle, etc., modify these objects by moving, scaling or rotating them,
|
||||
# and offers a couple of other utilities to manipulate further these objects,
|
||||
# such as decompose them (downgrade) into smaller elements.
|
||||
#
|
||||
# The functionality of the module is divided into GUI tools, usable from the
|
||||
# FreeCAD interface, and corresponding python functions, that can perform the same
|
||||
# operation programmatically.
|
||||
# visual interface, and corresponding python functions, that can perform
|
||||
# the same operation programmatically.
|
||||
#
|
||||
# @{
|
||||
|
||||
"""The Draft module offers a range of tools to create and manipulate basic 2D objects"""
|
||||
|
||||
import FreeCAD, math, sys, os, DraftVecUtils, WorkingPlane
|
||||
import DraftGeomUtils
|
||||
import draftutils.translate
|
||||
from FreeCAD import Vector
|
||||
import math
|
||||
import sys
|
||||
from PySide.QtCore import QT_TRANSLATE_NOOP
|
||||
|
||||
import FreeCAD
|
||||
from FreeCAD import Vector
|
||||
|
||||
import DraftVecUtils
|
||||
import WorkingPlane
|
||||
from draftutils.translate import translate
|
||||
|
||||
if FreeCAD.GuiUp:
|
||||
import FreeCADGui, Draft_rc
|
||||
from PySide import QtCore
|
||||
import FreeCADGui
|
||||
import Draft_rc
|
||||
gui = True
|
||||
#from DraftGui import translate
|
||||
# To prevent complaints from code checkers (flake8)
|
||||
True if Draft_rc.__name__ else False
|
||||
else:
|
||||
# def QT_TRANSLATE_NOOP(ctxt,txt):
|
||||
# return txt
|
||||
#print("FreeCAD Gui not present. Draft module will have some features disabled.")
|
||||
gui = False
|
||||
|
||||
translate = draftutils.translate.translate
|
||||
__title__ = "FreeCAD Draft Workbench"
|
||||
__author__ = ("Yorik van Havre, Werner Mayer, Martin Burbaum, Ken Cline, "
|
||||
"Dmitry Chigrin, Daniel Falck")
|
||||
__url__ = "https://www.freecadweb.org"
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# ---------------------------------------------------------------------------
|
||||
# Backwards compatibility
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
import DraftLayer
|
||||
_VisGroup = DraftLayer.Layer
|
||||
_ViewProviderVisGroup = DraftLayer.ViewProviderLayer
|
||||
makeLayer = DraftLayer.makeLayer
|
||||
# ---------------------------------------------------------------------------
|
||||
from DraftLayer import Layer as _VisGroup
|
||||
from DraftLayer import ViewProviderLayer as _ViewProviderVisGroup
|
||||
from DraftLayer import makeLayer
|
||||
|
||||
# import DraftFillet
|
||||
# Fillet = DraftFillet.Fillet
|
||||
# makeFillet = DraftFillet.makeFillet
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# ---------------------------------------------------------------------------
|
||||
# General functions
|
||||
#---------------------------------------------------------------------------
|
||||
import draftutils.utils
|
||||
import draftutils.gui_utils
|
||||
# ---------------------------------------------------------------------------
|
||||
from draftutils.utils import ARROW_TYPES as arrowtypes
|
||||
|
||||
arrowtypes = draftutils.utils.ARROW_TYPES
|
||||
from draftutils.utils import stringencodecoin
|
||||
from draftutils.utils import string_encode_coin
|
||||
|
||||
stringencodecoin = draftutils.utils.string_encode_coin
|
||||
string_encode_coin = draftutils.utils.string_encode_coin
|
||||
from draftutils.utils import typecheck
|
||||
from draftutils.utils import type_check
|
||||
|
||||
typecheck = draftutils.utils.type_check
|
||||
type_check = draftutils.utils.type_check
|
||||
from draftutils.utils import getParamType
|
||||
from draftutils.utils import get_param_type
|
||||
|
||||
getParamType = draftutils.utils.get_param_type
|
||||
get_param_type = draftutils.utils.get_param_type
|
||||
from draftutils.utils import getParam
|
||||
from draftutils.utils import get_param
|
||||
|
||||
getParam = draftutils.utils.get_param
|
||||
get_param = draftutils.utils.get_param
|
||||
from draftutils.utils import setParam
|
||||
from draftutils.utils import set_param
|
||||
|
||||
setParam = draftutils.utils.set_param
|
||||
set_param = draftutils.utils.set_param
|
||||
from draftutils.utils import precision
|
||||
from draftutils.utils import tolerance
|
||||
from draftutils.utils import epsilon
|
||||
|
||||
precision = draftutils.utils.precision
|
||||
tolerance = draftutils.utils.tolerance
|
||||
epsilon = draftutils.utils.epsilon
|
||||
from draftutils.utils import getRealName
|
||||
from draftutils.utils import get_real_name
|
||||
|
||||
getRealName = draftutils.utils.get_real_name
|
||||
get_real_name = draftutils.utils.get_real_name
|
||||
from draftutils.utils import getType
|
||||
from draftutils.utils import get_type
|
||||
|
||||
getType = draftutils.utils.get_type
|
||||
get_type = draftutils.utils.get_type
|
||||
from draftutils.utils import getObjectsOfType
|
||||
from draftutils.utils import get_objects_of_type
|
||||
|
||||
getObjectsOfType = draftutils.utils.get_objects_of_type
|
||||
get_objects_of_type = draftutils.utils.get_objects_of_type
|
||||
from draftutils.utils import isClone
|
||||
from draftutils.utils import is_clone
|
||||
|
||||
get3DView = draftutils.gui_utils.get_3d_view
|
||||
get_3d_view = draftutils.gui_utils.get_3d_view
|
||||
from draftutils.utils import getGroupNames
|
||||
from draftutils.utils import get_group_names
|
||||
|
||||
isClone = draftutils.utils.is_clone
|
||||
is_clone = draftutils.utils.is_clone
|
||||
from draftutils.utils import ungroup
|
||||
|
||||
getGroupNames = draftutils.utils.get_group_names
|
||||
get_group_names = draftutils.utils.get_group_names
|
||||
from draftutils.utils import getGroupContents
|
||||
from draftutils.utils import get_group_contents
|
||||
|
||||
ungroup = draftutils.utils.ungroup
|
||||
from draftutils.utils import printShape
|
||||
from draftutils.utils import print_shape
|
||||
|
||||
autogroup = draftutils.gui_utils.autogroup
|
||||
from draftutils.utils import compareObjects
|
||||
from draftutils.utils import compare_objects
|
||||
|
||||
dimSymbol = draftutils.gui_utils.dim_symbol
|
||||
dim_symbol = draftutils.gui_utils.dim_symbol
|
||||
from draftutils.utils import shapify
|
||||
|
||||
dimDash = draftutils.gui_utils.dim_dash
|
||||
dim_dash = draftutils.gui_utils.dim_dash
|
||||
from draftutils.utils import loadSvgPatterns
|
||||
from draftutils.utils import load_svg_patterns
|
||||
|
||||
shapify = draftutils.utils.shapify
|
||||
from draftutils.utils import svgpatterns
|
||||
from draftutils.utils import svg_patterns
|
||||
|
||||
getGroupContents = draftutils.utils.get_group_contents
|
||||
get_group_contents = draftutils.utils.get_group_contents
|
||||
from draftutils.utils import getMovableChildren
|
||||
from draftutils.utils import get_movable_children
|
||||
|
||||
removeHidden = draftutils.gui_utils.remove_hidden
|
||||
remove_hidden = draftutils.gui_utils.remove_hidden
|
||||
from draftutils.gui_utils import get3DView
|
||||
from draftutils.gui_utils import get_3d_view
|
||||
|
||||
printShape = draftutils.utils.print_shape
|
||||
print_shape = draftutils.utils.print_shape
|
||||
from draftutils.gui_utils import autogroup
|
||||
|
||||
compareObjects = draftutils.utils.compare_objects
|
||||
compare_objects = draftutils.utils.compare_objects
|
||||
from draftutils.gui_utils import dimSymbol
|
||||
from draftutils.gui_utils import dim_symbol
|
||||
|
||||
formatObject = draftutils.gui_utils.format_object
|
||||
format_object = draftutils.gui_utils.format_object
|
||||
from draftutils.gui_utils import dimDash
|
||||
from draftutils.gui_utils import dim_dash
|
||||
|
||||
getSelection = draftutils.gui_utils.get_selection
|
||||
get_selection = draftutils.gui_utils.get_selection
|
||||
from draftutils.gui_utils import removeHidden
|
||||
from draftutils.gui_utils import remove_hidden
|
||||
|
||||
getSelectionEx = draftutils.gui_utils.get_selection_ex
|
||||
get_selection_ex = draftutils.gui_utils.get_selection_ex
|
||||
from draftutils.gui_utils import formatObject
|
||||
from draftutils.gui_utils import format_object
|
||||
|
||||
select = draftutils.gui_utils.select
|
||||
from draftutils.gui_utils import getSelection
|
||||
from draftutils.gui_utils import get_selection
|
||||
|
||||
loadSvgPatterns = draftutils.utils.load_svg_patterns
|
||||
load_svg_patterns = draftutils.utils.load_svg_patterns
|
||||
from draftutils.gui_utils import getSelectionEx
|
||||
from draftutils.gui_utils import get_selection_ex
|
||||
|
||||
svgpatterns = draftutils.utils.svg_patterns
|
||||
svg_patterns = draftutils.utils.svg_patterns
|
||||
from draftutils.gui_utils import select
|
||||
|
||||
loadTexture = draftutils.gui_utils.load_texture
|
||||
load_texture = draftutils.gui_utils.load_texture
|
||||
|
||||
getMovableChildren = draftutils.utils.get_movable_children
|
||||
get_movable_children = draftutils.utils.get_movable_children
|
||||
from draftutils.gui_utils import loadTexture
|
||||
from draftutils.gui_utils import load_texture
|
||||
|
||||
|
||||
def makeCircle(radius, placement=None, face=None, startangle=None, endangle=None, support=None):
|
||||
@@ -715,7 +714,7 @@ def makeArray(baseobject,arg1,arg2,arg3,arg4=None,arg5=None,arg6=None,name="Arra
|
||||
_Array(obj)
|
||||
obj.Base = baseobject
|
||||
if arg6:
|
||||
if isinstance(arg1, (int, float)):
|
||||
if isinstance(arg1, (int, float, FreeCAD.Units.Quantity)):
|
||||
obj.ArrayType = "circular"
|
||||
obj.RadialDistance = arg1
|
||||
obj.TangentialDistance = arg2
|
||||
@@ -3875,6 +3874,7 @@ class _ViewProviderDimension(_ViewProviderDraft):
|
||||
return mode
|
||||
|
||||
def is_linked_to_circle(self):
|
||||
import DraftGeomUtils
|
||||
_obj = self.Object
|
||||
if _obj.LinkedGeometry and len(_obj.LinkedGeometry) == 1:
|
||||
lobj = _obj.LinkedGeometry[0][0]
|
||||
|
||||
+289
-246
File diff suppressed because it is too large
Load Diff
+92
-71
@@ -1,50 +1,69 @@
|
||||
# -*- coding: utf8 -*-
|
||||
#***************************************************************************
|
||||
#* Copyright (c) 2009, 2010 Yorik van Havre <[email protected]> *
|
||||
#* Copyright (c) 2009, 2010 Ken Cline <[email protected]> *
|
||||
#* *
|
||||
#* This program is free software; you can redistribute it and/or modify *
|
||||
#* it under the terms of the GNU Lesser General Public License (LGPL) *
|
||||
#* as published by the Free Software Foundation; either version 2 of *
|
||||
#* the License, or (at your option) any later version. *
|
||||
#* for detail see the LICENCE text file. *
|
||||
#* *
|
||||
#* This program is distributed in the hope that it will be useful, *
|
||||
#* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
#* GNU Library General Public License for more details. *
|
||||
#* *
|
||||
#* You should have received a copy of the GNU Library General Public *
|
||||
#* License along with this program; if not, write to the Free Software *
|
||||
#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
||||
#* USA *
|
||||
#* *
|
||||
#***************************************************************************
|
||||
|
||||
__title__="FreeCAD Draft Workbench GUI Tools"
|
||||
__author__ = "Yorik van Havre, Werner Mayer, Martin Burbaum, Ken Cline, Dmitry Chigrin"
|
||||
__url__ = "https://www.freecadweb.org"
|
||||
# ***************************************************************************
|
||||
# * Copyright (c) 2009, 2010 Yorik van Havre <[email protected]> *
|
||||
# * Copyright (c) 2009, 2010 Ken Cline <[email protected]> *
|
||||
# * *
|
||||
# * This program is free software; you can redistribute it and/or modify *
|
||||
# * it under the terms of the GNU Lesser General Public License (LGPL) *
|
||||
# * as published by the Free Software Foundation; either version 2 of *
|
||||
# * the License, or (at your option) any later version. *
|
||||
# * for detail see the LICENCE text file. *
|
||||
# * *
|
||||
# * This program is distributed in the hope that it will be useful, *
|
||||
# * but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
# * GNU Library General Public License for more details. *
|
||||
# * *
|
||||
# * You should have received a copy of the GNU Library General Public *
|
||||
# * License along with this program; if not, write to the Free Software *
|
||||
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
||||
# * USA *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
"""Provide GUI commands of the Draft Workbench.
|
||||
|
||||
This module loads all graphical commands of the Draft Workbench,
|
||||
that is, those actions that can be called from menus and buttons.
|
||||
This module must be imported only when the graphical user interface
|
||||
is available, for example, during the workbench definition in `IntiGui.py`.
|
||||
"""
|
||||
## @package DraftTools
|
||||
# \ingroup DRAFT
|
||||
# \brief GUI Commands of the Draft workbench
|
||||
# \brief Provide GUI commands of the Draft workbench.
|
||||
#
|
||||
# This module contains all the FreeCAD commands
|
||||
# of the Draft module
|
||||
# This module contains all the graphical commands of the Draft workbench,
|
||||
# that is, those actions that can be called from menus and buttons.
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# ---------------------------------------------------------------------------
|
||||
# Generic stuff
|
||||
#---------------------------------------------------------------------------
|
||||
# ---------------------------------------------------------------------------
|
||||
import math
|
||||
import sys
|
||||
from PySide import QtCore, QtGui
|
||||
from pivy import coin
|
||||
|
||||
import sys, FreeCAD, FreeCADGui, WorkingPlane, math, Draft, Draft_rc, DraftVecUtils
|
||||
import FreeCAD
|
||||
import FreeCADGui
|
||||
from FreeCAD import Vector
|
||||
from PySide import QtCore,QtGui
|
||||
import DraftGui
|
||||
from draftutils.todo import todo
|
||||
|
||||
import Draft
|
||||
import Draft_rc
|
||||
import DraftGui # Initializes the DraftToolBar class
|
||||
import DraftVecUtils
|
||||
import WorkingPlane
|
||||
from draftutils.todo import ToDo
|
||||
from draftutils.translate import translate
|
||||
import draftguitools.gui_snapper as gui_snapper
|
||||
import draftguitools.gui_trackers as trackers
|
||||
from pivy import coin
|
||||
|
||||
# The module is used to prevent complaints from code checkers (flake8)
|
||||
True if Draft_rc.__name__ else False
|
||||
True if DraftGui.__name__ else False
|
||||
|
||||
__title__ = "FreeCAD Draft Workbench GUI Tools"
|
||||
__author__ = ("Yorik van Havre, Werner Mayer, Martin Burbaum, Ken Cline, "
|
||||
"Dmitry Chigrin")
|
||||
__url__ = "https://www.freecadweb.org"
|
||||
|
||||
if not hasattr(FreeCADGui, "Snapper"):
|
||||
FreeCADGui.Snapper = gui_snapper.Snapper()
|
||||
@@ -52,20 +71,19 @@ if not hasattr(FreeCADGui, "Snapper"):
|
||||
if not hasattr(FreeCAD, "DraftWorkingPlane"):
|
||||
FreeCAD.DraftWorkingPlane = WorkingPlane.plane()
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# ---------------------------------------------------------------------------
|
||||
# Commands that have been migrated to their own modules
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
import draftguitools.gui_edit
|
||||
import draftguitools.gui_selectplane
|
||||
import draftguitools.gui_planeproxy
|
||||
# import DraftFillet
|
||||
import drafttaskpanels.task_shapestring as task_shapestring
|
||||
import drafttaskpanels.task_scale as task_scale
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# ---------------------------------------------------------------------------
|
||||
# Preflight stuff
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# update the translation engine
|
||||
FreeCADGui.updateLocale()
|
||||
|
||||
@@ -86,10 +104,9 @@ MODCONSTRAIN = MODS[Draft.getParam("modconstrain",0)]
|
||||
MODSNAP = MODS[Draft.getParam("modsnap",1)]
|
||||
MODALT = MODS[Draft.getParam("modalt",2)]
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# ---------------------------------------------------------------------------
|
||||
# General functions
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
def formatUnit(exp,unit="mm"):
|
||||
'''returns a formatting string to set a number to the correct unit'''
|
||||
return FreeCAD.Units.Quantity(exp,FreeCAD.Units.Length).UserString
|
||||
@@ -221,12 +238,9 @@ def setMod(args,mod,state):
|
||||
args["AltDown"] = state
|
||||
|
||||
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# ---------------------------------------------------------------------------
|
||||
# Base Class
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
class DraftTool:
|
||||
"""The base class of all Draft Tools"""
|
||||
|
||||
@@ -296,7 +310,7 @@ class DraftTool:
|
||||
pass
|
||||
self.call = None
|
||||
if self.commitList:
|
||||
todo.delayCommit(self.commitList)
|
||||
ToDo.delayCommit(self.commitList)
|
||||
self.commitList = []
|
||||
|
||||
def commit(self,name,func):
|
||||
@@ -334,10 +348,9 @@ class DraftTool:
|
||||
return qr,sup,points,fil
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# ---------------------------------------------------------------------------
|
||||
# Geometry constructors
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
def redraw3DView():
|
||||
"""redraw3DView(): forces a redraw of 3d view."""
|
||||
try:
|
||||
@@ -463,7 +476,7 @@ class Line(Creator):
|
||||
# object already deleted, for some reason
|
||||
pass
|
||||
else:
|
||||
todo.delay(self.doc.removeObject,old)
|
||||
ToDo.delay(self.doc.removeObject, old)
|
||||
self.obj = None
|
||||
|
||||
def undolast(self):
|
||||
@@ -575,7 +588,7 @@ class Wire(Line):
|
||||
pts = pts.replace("Vector","FreeCAD.Vector")
|
||||
rems = ["FreeCAD.ActiveDocument.removeObject(\""+o.Name+"\")" for o in FreeCADGui.Selection.getSelection()]
|
||||
FreeCADGui.addModule("Draft")
|
||||
todo.delayCommit([(translate("draft","Convert to Wire"),
|
||||
ToDo.delayCommit([(translate("draft", "Convert to Wire"),
|
||||
['wire = Draft.makeWire(['+pts+'])']+rems+['Draft.autogroup(wire)',
|
||||
'FreeCAD.ActiveDocument.recompute()'])])
|
||||
return
|
||||
@@ -665,7 +678,7 @@ class BSpline(Line):
|
||||
if self.obj:
|
||||
# remove temporary object, if any
|
||||
old = self.obj.Name
|
||||
todo.delay(self.doc.removeObject,old)
|
||||
ToDo.delay(self.doc.removeObject, old)
|
||||
if (len(self.node) > 1):
|
||||
try:
|
||||
# building command string
|
||||
@@ -785,7 +798,7 @@ class BezCurve(Line):
|
||||
if self.obj:
|
||||
# remove temporary object, if any
|
||||
old = self.obj.Name
|
||||
todo.delay(self.doc.removeObject,old)
|
||||
ToDo.delay(self.doc.removeObject, old)
|
||||
if (len(self.node) > 1):
|
||||
try:
|
||||
# building command string
|
||||
@@ -944,7 +957,7 @@ class CubicBezCurve(Line):
|
||||
if self.obj:
|
||||
# remove temporary object, if any
|
||||
old = self.obj.Name
|
||||
todo.delay(self.doc.removeObject,old)
|
||||
ToDo.delay(self.doc.removeObject, old)
|
||||
if closed == False :
|
||||
cleannd=(len(self.node)-1) % self.degree
|
||||
if cleannd == 0 : self.node = self.node[0:-3]
|
||||
@@ -2225,14 +2238,22 @@ class Dimension(Creator):
|
||||
if not self.cont:
|
||||
self.finish()
|
||||
|
||||
|
||||
class ShapeString(Creator):
|
||||
"""This class creates a shapestring feature."""
|
||||
"""The Draft_ShapeString FreeCAD command definition."""
|
||||
|
||||
def GetResources(self):
|
||||
return {'Pixmap' : 'Draft_ShapeString',
|
||||
'Accel' : "S, S",
|
||||
'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_ShapeString", "Shape from text..."),
|
||||
'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_ShapeString", "Creates text string in shapes.")}
|
||||
"""Set icon, menu and tooltip."""
|
||||
_menu = "Shape from text"
|
||||
_tooltip = ("Creates a shape from a text string by choosing "
|
||||
"a specific font and a placement.\n"
|
||||
"The closed shapes can be used for extrusions "
|
||||
"and boolean operations.")
|
||||
d = {'Pixmap': 'Draft_ShapeString',
|
||||
'Accel': "S, S",
|
||||
'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_ShapeString", _menu),
|
||||
'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_ShapeString", _tooltip)}
|
||||
return d
|
||||
|
||||
def Activated(self):
|
||||
name = translate("draft","ShapeString")
|
||||
@@ -2248,7 +2269,7 @@ class ShapeString(Creator):
|
||||
pass
|
||||
self.task = task_shapestring.ShapeStringTaskPanel()
|
||||
self.task.sourceCmd = self
|
||||
todo.delay(FreeCADGui.Control.showDialog,self.task)
|
||||
ToDo.delay(FreeCADGui.Control.showDialog, self.task)
|
||||
else:
|
||||
self.dialog = None
|
||||
self.text = ''
|
||||
@@ -2408,7 +2429,7 @@ class Move(Modifier):
|
||||
ghost.finalize()
|
||||
if cont and self.ui:
|
||||
if self.ui.continueMode:
|
||||
todo.delayAfter(self.Activated,[])
|
||||
ToDo.delayAfter(self.Activated, [])
|
||||
Modifier.finish(self)
|
||||
|
||||
def action(self,arg):
|
||||
@@ -2750,7 +2771,7 @@ class Rotate(Modifier):
|
||||
ghost.finalize()
|
||||
if cont and self.ui:
|
||||
if self.ui.continueMode:
|
||||
todo.delayAfter(self.Activated,[])
|
||||
ToDo.delayAfter(self.Activated, [])
|
||||
Modifier.finish(self)
|
||||
if self.doc:
|
||||
self.doc.recompute()
|
||||
@@ -4133,9 +4154,9 @@ class Scale(Modifier):
|
||||
self.view.removeEventCallback("SoEvent",self.call)
|
||||
self.task = task_scale.ScaleTaskPanel()
|
||||
self.task.sourceCmd = self
|
||||
todo.delay(FreeCADGui.Control.showDialog,self.task)
|
||||
todo.delay(self.task.xValue.selectAll,None)
|
||||
todo.delay(self.task.xValue.setFocus,None)
|
||||
ToDo.delay(FreeCADGui.Control.showDialog, self.task)
|
||||
ToDo.delay(self.task.xValue.selectAll, None)
|
||||
ToDo.delay(self.task.xValue.setFocus, None)
|
||||
for ghost in self.ghosts:
|
||||
ghost.on()
|
||||
elif len(self.node) == 2:
|
||||
@@ -4788,7 +4809,7 @@ class Point(Creator):
|
||||
['point = Draft.makePoint('+str(self.stack[0][0])+','+str(self.stack[0][1])+','+str(self.stack[0][2])+')',
|
||||
'Draft.autogroup(point)',
|
||||
'FreeCAD.ActiveDocument.recompute()']))
|
||||
todo.delayCommit(commitlist)
|
||||
ToDo.delayCommit(commitlist)
|
||||
FreeCADGui.Snapper.off()
|
||||
self.finish()
|
||||
|
||||
@@ -4856,7 +4877,7 @@ class Draft_Clone(Modifier):
|
||||
def finish(self,close=False):
|
||||
Modifier.finish(self,close=False)
|
||||
if self.moveAfterCloning:
|
||||
todo.delay(FreeCADGui.runCommand,"Draft_Move")
|
||||
ToDo.delay(FreeCADGui.runCommand, "Draft_Move")
|
||||
|
||||
|
||||
class ToggleGrid():
|
||||
|
||||
@@ -1,19 +1,3 @@
|
||||
## \defgroup DRAFTVECUTILS DraftVecUtils
|
||||
# \ingroup UTILITIES
|
||||
# \brief Vector math utilities used in Draft workbench
|
||||
#
|
||||
# Vector math utilities used primarily in the Draft workbench
|
||||
# but which can also be used in other workbenches and in macros.
|
||||
"""\defgroup DRAFTVECUTILS DraftVecUtils
|
||||
\ingroup UTILITIES
|
||||
\brief Vector math utilities used in Draft workbench
|
||||
|
||||
Vector math utilities used primarily in the Draft workbench
|
||||
but which can also be used in other workbenches and in macros.
|
||||
"""
|
||||
# Check code with
|
||||
# flake8 --ignore=E226,E266,E401,W503
|
||||
|
||||
# ***************************************************************************
|
||||
# * Copyright (c) 2009, 2010 Yorik van Havre <[email protected]> *
|
||||
# * Copyright (c) 2009, 2010 Ken Cline <[email protected]> *
|
||||
@@ -35,19 +19,32 @@ but which can also be used in other workbenches and in macros.
|
||||
# * USA *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
"""Provide vector math utilities used in the Draft workbench.
|
||||
|
||||
Vector math utilities used primarily in the Draft workbench
|
||||
but which can also be used in other workbenches and in macros.
|
||||
"""
|
||||
## \defgroup DRAFTVECUTILS DraftVecUtils
|
||||
# \ingroup UTILITIES
|
||||
# \brief Vector math utilities used in Draft workbench
|
||||
#
|
||||
# Vector math utilities used primarily in the Draft workbench
|
||||
# but which can also be used in other workbenches and in macros.
|
||||
|
||||
# Check code with
|
||||
# flake8 --ignore=E226,E266,E401,W503
|
||||
|
||||
import math
|
||||
import sys
|
||||
|
||||
import FreeCAD
|
||||
from FreeCAD import Vector
|
||||
import draftutils.messages as messages
|
||||
|
||||
__title__ = "FreeCAD Draft Workbench - Vector library"
|
||||
__author__ = "Yorik van Havre, Werner Mayer, Martin Burbaum, Ken Cline"
|
||||
__url__ = "https://www.freecadweb.org"
|
||||
|
||||
## \addtogroup DRAFTVECUTILS
|
||||
# @{
|
||||
|
||||
import sys
|
||||
import math, FreeCAD
|
||||
from FreeCAD import Vector, Matrix
|
||||
from FreeCAD import Console as FCC
|
||||
|
||||
# Python 2 has two integer types, int and long.
|
||||
# In Python 3 there is no 'long' anymore, so make it 'int'.
|
||||
try:
|
||||
@@ -57,6 +54,9 @@ except NameError:
|
||||
|
||||
params = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Draft")
|
||||
|
||||
## \addtogroup DRAFTVECUTILS
|
||||
# @{
|
||||
|
||||
|
||||
def precision():
|
||||
"""Get the number of decimal numbers used for precision.
|
||||
@@ -97,16 +97,15 @@ def typecheck(args_and_types, name="?"):
|
||||
Defaults to `'?'`. The name of the check.
|
||||
|
||||
Raises
|
||||
-------
|
||||
------
|
||||
TypeError
|
||||
If the first element in the tuple is not an instance of the second
|
||||
element.
|
||||
"""
|
||||
for v, t in args_and_types:
|
||||
if not isinstance(v, t):
|
||||
_msg = ("typecheck[" + str(name) + "]: "
|
||||
+ str(v) + " is not " + str(t) + "\n")
|
||||
FCC.PrintWarning(_msg)
|
||||
_msg = "typecheck[{0}]: {1} is not {2}".format(name, v, t)
|
||||
messages._wrn(_msg)
|
||||
raise TypeError("fcvec." + str(name))
|
||||
|
||||
|
||||
@@ -208,7 +207,7 @@ def equals(u, v):
|
||||
The second vector.
|
||||
|
||||
Returns
|
||||
------
|
||||
-------
|
||||
bool
|
||||
`True` if the vectors are within the precision, `False` otherwise.
|
||||
"""
|
||||
@@ -497,9 +496,9 @@ def rotate(u, angle, axis=Vector(0, 0, 1)):
|
||||
ys = y * s
|
||||
zs = z * s
|
||||
|
||||
m = Matrix(c + x*x*t, xyt - zs, xzt + ys, 0,
|
||||
xyt + zs, c + y*y*t, yzt - xs, 0,
|
||||
xzt - ys, yzt + xs, c + z*z*t, 0)
|
||||
m = FreeCAD.Matrix(c + x*x*t, xyt - zs, xzt + ys, 0,
|
||||
xyt + zs, c + y*y*t, yzt - xs, 0,
|
||||
xzt - ys, yzt + xs, c + z*z*t, 0)
|
||||
|
||||
return m.multiply(u)
|
||||
|
||||
@@ -547,7 +546,7 @@ def getRotation(vector, reference=Vector(1, 0, 0)):
|
||||
|
||||
|
||||
def isNull(vector):
|
||||
"""Returns `False` if each of the components of the vector is zero.
|
||||
"""Return False if each of the components of the vector is zero.
|
||||
|
||||
Due to rounding errors, an element is probably never going to be
|
||||
exactly zero. Therefore, it rounds the element by the number
|
||||
|
||||
+34
-29
@@ -1,31 +1,36 @@
|
||||
#***************************************************************************
|
||||
#* Copyright (c) 2009 Yorik van Havre <[email protected]> *
|
||||
#* *
|
||||
#* This program is free software; you can redistribute it and/or modify *
|
||||
#* it under the terms of the GNU Lesser General Public License (LGPL) *
|
||||
#* as published by the Free Software Foundation; either version 2 of *
|
||||
#* the License, or (at your option) any later version. *
|
||||
#* for detail see the LICENCE text file. *
|
||||
#* *
|
||||
#* This program is distributed in the hope that it will be useful, *
|
||||
#* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
#* GNU Library General Public License for more details. *
|
||||
#* *
|
||||
#* You should have received a copy of the GNU Library General Public *
|
||||
#* License along with this program; if not, write to the Free Software *
|
||||
#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
||||
#* USA *
|
||||
#* *
|
||||
#***************************************************************************
|
||||
# ***************************************************************************
|
||||
# * Copyright (c) 2009 Yorik van Havre <[email protected]> *
|
||||
# * *
|
||||
# * This program is free software; you can redistribute it and/or modify *
|
||||
# * it under the terms of the GNU Lesser General Public License (LGPL) *
|
||||
# * as published by the Free Software Foundation; either version 2 of *
|
||||
# * the License, or (at your option) any later version. *
|
||||
# * for detail see the LICENCE text file. *
|
||||
# * *
|
||||
# * This program is distributed in the hope that it will be useful, *
|
||||
# * but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
# * GNU Library General Public License for more details. *
|
||||
# * *
|
||||
# * You should have received a copy of the GNU Library General Public *
|
||||
# * License along with this program; if not, write to the Free Software *
|
||||
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
||||
# * USA *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
"""Initialization file of the workbench, non-GUI."""
|
||||
|
||||
import FreeCAD as App
|
||||
|
||||
# add Import/Export types
|
||||
App.addImportType("Autodesk DXF 2D (*.dxf)","importDXF")
|
||||
App.addImportType("SVG as geometry (*.svg)","importSVG")
|
||||
App.addImportType("Open CAD Format (*.oca *.gcad)","importOCA")
|
||||
App.addImportType("Common airfoil data (*.dat)","importAirfoilDAT")
|
||||
App.addExportType("Autodesk DXF 2D (*.dxf)","importDXF")
|
||||
App.addExportType("Flattened SVG (*.svg)","importSVG")
|
||||
App.addExportType("Open CAD Format (*.oca)","importOCA")
|
||||
App.addImportType("Autodesk DWG 2D (*.dwg)","importDWG")
|
||||
App.addExportType("Autodesk DWG 2D (*.dwg)","importDWG")
|
||||
App.addImportType("Autodesk DXF 2D (*.dxf)", "importDXF")
|
||||
App.addImportType("SVG as geometry (*.svg)", "importSVG")
|
||||
App.addImportType("Open CAD Format (*.oca *.gcad)", "importOCA")
|
||||
App.addImportType("Common airfoil data (*.dat)", "importAirfoilDAT")
|
||||
App.addExportType("Autodesk DXF 2D (*.dxf)", "importDXF")
|
||||
App.addExportType("Flattened SVG (*.svg)", "importSVG")
|
||||
App.addExportType("Open CAD Format (*.oca)", "importOCA")
|
||||
App.addImportType("Autodesk DWG 2D (*.dwg)", "importDWG")
|
||||
App.addExportType("Autodesk DWG 2D (*.dwg)", "importDWG")
|
||||
|
||||
App.__unit_test__ += ["TestDraft"]
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"""Initialization of the Draft workbench (graphical interface)."""
|
||||
# ***************************************************************************
|
||||
# * Copyright (c) 2009 Yorik van Havre <[email protected]> *
|
||||
# * *
|
||||
@@ -19,7 +18,10 @@
|
||||
# * USA *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
"""Initialization of the Draft workbench (graphical interface)."""
|
||||
|
||||
import os
|
||||
|
||||
import FreeCAD
|
||||
import FreeCADGui
|
||||
|
||||
@@ -173,4 +175,4 @@ FreeCADGui.addPreferencePage(":/ui/preferences-dwg.ui", QT_TRANSLATE_NOOP("Draft
|
||||
FreeCADGui.addPreferencePage(":/ui/preferences-svg.ui", QT_TRANSLATE_NOOP("Draft", "Import-Export"))
|
||||
FreeCADGui.addPreferencePage(":/ui/preferences-oca.ui", QT_TRANSLATE_NOOP("Draft", "Import-Export"))
|
||||
|
||||
FreeCAD.__unit_test__ += ["TestDraft"]
|
||||
FreeCAD.__unit_test__ += ["TestDraftGui"]
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
<file>icons/Draft_Offset.svg</file>
|
||||
<file>icons/Draft_PathArray.svg</file>
|
||||
<file>icons/Draft_PathLinkArray.svg</file>
|
||||
<file>icons/Draft_PlaneProxy.svg</file>
|
||||
<file>icons/Draft_Point.svg</file>
|
||||
<file>icons/Draft_PointArray.svg</file>
|
||||
<file>icons/Draft_PolarArray.svg</file>
|
||||
|
||||
@@ -0,0 +1,436 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<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"
|
||||
version="1.1"
|
||||
id="svg3612"
|
||||
height="64px"
|
||||
width="64px">
|
||||
<defs
|
||||
id="defs3614">
|
||||
<linearGradient
|
||||
id="linearGradient3809">
|
||||
<stop
|
||||
id="stop3811"
|
||||
offset="0"
|
||||
style="stop-color:#06989a;stop-opacity:1" />
|
||||
<stop
|
||||
id="stop3813"
|
||||
offset="1"
|
||||
style="stop-color:#34e0e2;stop-opacity:1" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
r="34.345188"
|
||||
fy="672.79736"
|
||||
fx="225.26402"
|
||||
cy="672.79736"
|
||||
cx="225.26402"
|
||||
gradientTransform="matrix(1,0,0,0.6985294,0,202.82863)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="radialGradient3684"
|
||||
xlink:href="#linearGradient3144-6" />
|
||||
<linearGradient
|
||||
id="linearGradient3144-6">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#ffffff;stop-opacity:1"
|
||||
id="stop3146-9" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#ffffff;stop-opacity:0"
|
||||
id="stop3148-2" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
r="34.345188"
|
||||
fy="672.79736"
|
||||
fx="225.26402"
|
||||
cy="672.79736"
|
||||
cx="225.26402"
|
||||
gradientTransform="matrix(1,0,0,0.6985294,0,202.82863)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="radialGradient3686"
|
||||
xlink:href="#linearGradient3144-6" />
|
||||
<linearGradient
|
||||
id="linearGradient3701">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#ffffff;stop-opacity:1"
|
||||
id="stop3703" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#ffffff;stop-opacity:0"
|
||||
id="stop3705" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
r="34.345188"
|
||||
fy="672.79736"
|
||||
fx="225.26402"
|
||||
cy="672.79736"
|
||||
cx="225.26402"
|
||||
gradientTransform="matrix(1,0,0,0.6985294,0,202.82863)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="radialGradient3688"
|
||||
xlink:href="#linearGradient3144-6" />
|
||||
<linearGradient
|
||||
id="linearGradient3708">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#ffffff;stop-opacity:1"
|
||||
id="stop3710" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#ffffff;stop-opacity:0"
|
||||
id="stop3712" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
xlink:href="#linearGradient3144-6"
|
||||
id="radialGradient3723"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1,0,0,0.6985294,0,202.82863)"
|
||||
cx="225.26402"
|
||||
cy="672.79736"
|
||||
fx="225.26402"
|
||||
fy="672.79736"
|
||||
r="34.345188" />
|
||||
<linearGradient
|
||||
y2="115.01974"
|
||||
x2="654.80023"
|
||||
y1="77.046234"
|
||||
x1="696.67322"
|
||||
gradientTransform="matrix(0.2210246,-0.5789261,-0.71699693,-0.35346705,519.98085,464.19243)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="linearGradient3934"
|
||||
xlink:href="#linearGradient3864-0-0" />
|
||||
<linearGradient
|
||||
id="linearGradient3864-0-0">
|
||||
<stop
|
||||
style="stop-color:#0619c0;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3866-5-7" />
|
||||
<stop
|
||||
style="stop-color:#379cfb;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3868-7-6" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="30.27434"
|
||||
x2="619.30328"
|
||||
y1="44.024342"
|
||||
x1="597.77283"
|
||||
id="linearGradient3942"
|
||||
xlink:href="#linearGradient3377" />
|
||||
<linearGradient
|
||||
id="linearGradient3377">
|
||||
<stop
|
||||
style="stop-color:#ffaa00;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3379" />
|
||||
<stop
|
||||
style="stop-color:#faff2b;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3381" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
y2="139.40982"
|
||||
x2="650.70459"
|
||||
y1="77.046234"
|
||||
x1="696.67322"
|
||||
gradientTransform="matrix(0.2210246,-0.5789261,-0.71699693,-0.35346705,536.41251,472.3612)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="linearGradient3657"
|
||||
xlink:href="#linearGradient3864-0" />
|
||||
<linearGradient
|
||||
id="linearGradient3864-0">
|
||||
<stop
|
||||
style="stop-color:#0619c0;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3866-5" />
|
||||
<stop
|
||||
style="stop-color:#379cfb;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3868-7" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="10"
|
||||
x2="22"
|
||||
y1="52"
|
||||
x1="34"
|
||||
id="linearGradient3815"
|
||||
xlink:href="#linearGradient3791-6" />
|
||||
<linearGradient
|
||||
id="linearGradient6349">
|
||||
<stop
|
||||
style="stop-color:#000000;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop6351" />
|
||||
<stop
|
||||
style="stop-color:#000000;stop-opacity:0;"
|
||||
offset="1"
|
||||
id="stop6353" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3377-3">
|
||||
<stop
|
||||
style="stop-color:#0019a3;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3379-6" />
|
||||
<stop
|
||||
style="stop-color:#0069ff;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3381-7" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
xlink:href="#linearGradient3377-3"
|
||||
id="linearGradient3383"
|
||||
x1="901.1875"
|
||||
y1="1190.875"
|
||||
x2="1267.9062"
|
||||
y2="1190.875"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(-1,0,0,1,2199.356,0)" />
|
||||
<radialGradient
|
||||
xlink:href="#linearGradient6349"
|
||||
id="radialGradient6355"
|
||||
cx="1103.6399"
|
||||
cy="1424.4465"
|
||||
fx="1103.6399"
|
||||
fy="1424.4465"
|
||||
r="194.40614"
|
||||
gradientTransform="matrix(-1.4307499,-1.3605156e-7,-1.202713e-8,0.1264801,2674.7488,1244.2826)"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
id="linearGradient3791-6">
|
||||
<stop
|
||||
style="stop-color:#204a87;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop3793-7" />
|
||||
<stop
|
||||
style="stop-color:#729fcf;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop3795-5" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
xlink:href="#linearGradient3791-6"
|
||||
id="linearGradient3820"
|
||||
x1="939.98767"
|
||||
y1="1097.5122"
|
||||
x2="893.2572"
|
||||
y2="989.77716"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
y2="989.77716"
|
||||
x2="893.2572"
|
||||
y1="1097.5122"
|
||||
x1="939.98767"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="linearGradient3834-6"
|
||||
xlink:href="#linearGradient3791-6"
|
||||
gradientTransform="matrix(1.251547,0,0,1.2214422,104.06364,54.837797)" />
|
||||
<linearGradient
|
||||
xlink:href="#linearGradient3791-6"
|
||||
id="linearGradient911"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.17119448,0,0,0.16707656,-190.70037,-126.91093)"
|
||||
x1="939.98767"
|
||||
y1="1097.5122"
|
||||
x2="893.2572"
|
||||
y2="1049.63" />
|
||||
<linearGradient
|
||||
xlink:href="#linearGradient3791-6"
|
||||
id="linearGradient926"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.251547,0,0,1.2214422,104.06352,186.42979)"
|
||||
x1="939.98773"
|
||||
y1="989.77716"
|
||||
x2="893.2572"
|
||||
y2="941.8949" />
|
||||
<linearGradient
|
||||
id="linearGradient3354">
|
||||
<stop
|
||||
style="stop-color:#2157c7;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3356" />
|
||||
<stop
|
||||
style="stop-color:#6daaff;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3358" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
gradientTransform="matrix(0,-1.4500001,1.4705882,0,-15.05882,91.45)"
|
||||
y2="36.079998"
|
||||
x2="21.689653"
|
||||
y1="29.279999"
|
||||
x1="56.172409"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="linearGradient3036"
|
||||
xlink:href="#linearGradient3895" />
|
||||
<linearGradient
|
||||
id="linearGradient3895">
|
||||
<stop
|
||||
style="stop-color:#729fcf;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3897" />
|
||||
<stop
|
||||
style="stop-color:#204a87;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3899" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
y2="36.079998"
|
||||
x2="21.689653"
|
||||
y1="29.279999"
|
||||
x1="56.172409"
|
||||
gradientTransform="matrix(0,-0.58000003,0.58823527,0,13.176471,38.379999)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="linearGradient3918-3"
|
||||
xlink:href="#linearGradient3895" />
|
||||
<linearGradient
|
||||
y2="36.079998"
|
||||
x2="21.689653"
|
||||
y1="29.279999"
|
||||
x1="56.172409"
|
||||
gradientTransform="matrix(0.58000003,0,0,0.58823527,25.620001,13.176471)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="linearGradient3029-6"
|
||||
xlink:href="#linearGradient3895" />
|
||||
<linearGradient
|
||||
xlink:href="#linearGradient3895"
|
||||
id="linearGradient3154"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0,-0.58000003,0.58823527,0,-64.65713,39.527336)"
|
||||
x1="45.482754"
|
||||
y1="11.599999"
|
||||
x2="-23.482759"
|
||||
y2="52.400002" />
|
||||
<linearGradient
|
||||
xlink:href="#linearGradient3895"
|
||||
id="linearGradient3156"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(-0.58000003,0,0,0.58823527,-39.453602,14.323808)"
|
||||
x1="31.689651"
|
||||
y1="-2.0000007"
|
||||
x2="-9.6896563"
|
||||
y2="66" />
|
||||
<linearGradient
|
||||
xlink:href="#linearGradient3895"
|
||||
id="linearGradient3158"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.58000003,0,0,0.58823527,-52.2136,14.323808)"
|
||||
x1="-9.6896563"
|
||||
y1="-2.0000007"
|
||||
x2="31.689651"
|
||||
y2="66" />
|
||||
<linearGradient
|
||||
xlink:href="#linearGradient3895"
|
||||
id="linearGradient3160"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0,0.58000003,0.58823527,0,-64.65713,26.767338)"
|
||||
x1="-23.482759"
|
||||
y1="11.599999"
|
||||
x2="45.482754"
|
||||
y2="52.400002" />
|
||||
<linearGradient
|
||||
xlink:href="#linearGradient3895"
|
||||
id="linearGradient3936"
|
||||
x1="20"
|
||||
y1="12"
|
||||
x2="44"
|
||||
y2="52"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(-77.833601,1.147337)" />
|
||||
</defs>
|
||||
<path
|
||||
style="fill:url(#linearGradient3815);fill-opacity:1;stroke:#0b1521;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 35,3 9,16 v 45 h 4 L 51.020744,40.40543 51,3 Z"
|
||||
id="path3305" />
|
||||
<path
|
||||
style="fill:#16d0d2;stroke:#0b1521;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 3,19 35,3"
|
||||
id="path3190" />
|
||||
<path
|
||||
style="fill:none;stroke:#729fcf;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 35.5,5 11,17.2 V 59 h 1.5 L 49,39.2 V 5 Z"
|
||||
id="path3305-1" />
|
||||
<path
|
||||
style="fill:#16d0d2;stroke:#0b1521;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 3,43 61,11"
|
||||
id="path3190-7" />
|
||||
<path
|
||||
style="fill:#16d0d2;stroke:#0b1521;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 13,61 61,35"
|
||||
id="path3190-9" />
|
||||
<path
|
||||
style="fill:#16d0d2;stroke:#0b1521;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 51,61 61,55"
|
||||
id="path3190-1" />
|
||||
<path
|
||||
style="fill:#16d0d2;stroke:#0b1521;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 9,3 V 61"
|
||||
id="path3224" />
|
||||
<path
|
||||
style="fill:#16d0d2;stroke:#0b1521;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 31,3 V 61"
|
||||
id="path3224-4" />
|
||||
<path
|
||||
id="rect3170"
|
||||
d="M 19,25 43,13 V 33 L 19,45 Z"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#0b1521;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" />
|
||||
<path
|
||||
style="fill:#16d0d2;stroke:#0b1521;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 51,3 V 61"
|
||||
id="path3224-7" />
|
||||
<metadata
|
||||
id="metadata5520">
|
||||
<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:license
|
||||
rdf:resource="" />
|
||||
<dc:date>Mon Oct 10 13:44:52 2011 +0000</dc:date>
|
||||
<dc:creator>
|
||||
<cc:Agent>
|
||||
<dc:title>[wmayer]</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:creator>
|
||||
<dc:rights>
|
||||
<cc:Agent>
|
||||
<dc:title>FreeCAD LGPL2+</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:rights>
|
||||
<dc:publisher>
|
||||
<cc:Agent>
|
||||
<dc:title>FreeCAD</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:publisher>
|
||||
<dc:identifier>FreeCAD/src/Mod/Draft/Resources/icons/Draft_PlaneProxy.svg</dc:identifier>
|
||||
<dc:relation>http://www.freecadweb.org/wiki/index.php?title=Artwork</dc:relation>
|
||||
<dc:contributor>
|
||||
<cc:Agent>
|
||||
<dc:title>[agryson] Alexander Gryson, vocx</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:contributor>
|
||||
<dc:subject>
|
||||
<rdf:Bag>
|
||||
<rdf:li>rectangle</rdf:li>
|
||||
<rdf:li>grid</rdf:li>
|
||||
<rdf:li>plane</rdf:li>
|
||||
</rdf:Bag>
|
||||
</dc:subject>
|
||||
<dc:description>A rectangle sitting on a plane aligned to a grid that is going into the page from the left to the right; color variation</dc:description>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
transform="matrix(0.1378133,0,0,0.1378133,-299.23059,-137.20541)"
|
||||
id="g4351" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 14 KiB |
+18
-22
@@ -1,12 +1,3 @@
|
||||
"""Unit tests for the Draft workbench.
|
||||
|
||||
From the terminal, run the following:
|
||||
FreeCAD -t TestDraft
|
||||
|
||||
From within FreeCAD, run the following:
|
||||
import Test, TestDraft
|
||||
Test.runTestsFromModule(TestDraft)
|
||||
"""
|
||||
# ***************************************************************************
|
||||
# * Copyright (c) 2013 Yorik van Havre <[email protected]> *
|
||||
# * Copyright (c) 2019 Eliud Cabrera Castillo <[email protected]> *
|
||||
@@ -30,6 +21,17 @@ Test.runTestsFromModule(TestDraft)
|
||||
# * USA *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
"""Unit tests for the Draft workbench, non-GUI only.
|
||||
|
||||
From the terminal, run the following:
|
||||
FreeCAD -t TestDraft
|
||||
|
||||
From within FreeCAD, run the following:
|
||||
import Test, TestDraft
|
||||
Test.runTestsFromModule(TestDraft)
|
||||
|
||||
For the GUI-only tests see TestDraftGui.
|
||||
"""
|
||||
|
||||
# ===========================================================================
|
||||
# The unit tests can be run from the operating system terminal, or from
|
||||
@@ -94,20 +96,17 @@ Test.runTestsFromModule(TestDraft)
|
||||
|
||||
# Import tests
|
||||
from drafttests.test_import import DraftImport as DraftTest01
|
||||
from drafttests.test_import_gui import DraftGuiImport as DraftTest02
|
||||
from drafttests.test_import_tools import DraftImportTools as DraftTest03
|
||||
from drafttests.test_pivy import DraftPivy as DraftTest04
|
||||
|
||||
# Objects tests
|
||||
from drafttests.test_creation import DraftCreation as DraftTest05
|
||||
from drafttests.test_modification import DraftModification as DraftTest06
|
||||
from drafttests.test_creation import DraftCreation as DraftTest02
|
||||
from drafttests.test_modification import DraftModification as DraftTest03
|
||||
|
||||
# Handling of file formats tests
|
||||
from drafttests.test_svg import DraftSVG as DraftTest07
|
||||
from drafttests.test_dxf import DraftDXF as DraftTest08
|
||||
from drafttests.test_dwg import DraftDWG as DraftTest09
|
||||
from drafttests.test_oca import DraftOCA as DraftTest10
|
||||
from drafttests.test_airfoildat import DraftAirfoilDAT as DraftTest11
|
||||
from drafttests.test_svg import DraftSVG as DraftTest04
|
||||
from drafttests.test_dxf import DraftDXF as DraftTest05
|
||||
from drafttests.test_dwg import DraftDWG as DraftTest06
|
||||
from drafttests.test_oca import DraftOCA as DraftTest07
|
||||
from drafttests.test_airfoildat import DraftAirfoilDAT as DraftTest08
|
||||
|
||||
# Use the modules so that code checkers don't complain (flake8)
|
||||
True if DraftTest01 else False
|
||||
@@ -118,6 +117,3 @@ True if DraftTest05 else False
|
||||
True if DraftTest06 else False
|
||||
True if DraftTest07 else False
|
||||
True if DraftTest08 else False
|
||||
True if DraftTest09 else False
|
||||
True if DraftTest10 else False
|
||||
True if DraftTest11 else False
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
# ***************************************************************************
|
||||
# * Copyright (c) 2013 Yorik van Havre <[email protected]> *
|
||||
# * Copyright (c) 2020 Eliud Cabrera Castillo <[email protected]> *
|
||||
# * *
|
||||
# * This file is part of the FreeCAD CAx development system. *
|
||||
# * *
|
||||
# * This program is free software; you can redistribute it and/or modify *
|
||||
# * it under the terms of the GNU Lesser General Public License (LGPL) *
|
||||
# * as published by the Free Software Foundation; either version 2 of *
|
||||
# * the License, or (at your option) any later version. *
|
||||
# * for detail see the LICENCE text file. *
|
||||
# * *
|
||||
# * FreeCAD is distributed in the hope that it will be useful, *
|
||||
# * but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
# * GNU Library General Public License for more details. *
|
||||
# * *
|
||||
# * You should have received a copy of the GNU Library General Public *
|
||||
# * License along with FreeCAD; if not, write to the Free Software *
|
||||
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
||||
# * USA *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
"""Unit tests for the Draft workbench, GUI only.
|
||||
|
||||
From the terminal, run the following:
|
||||
FreeCAD -t TestDraftGui
|
||||
|
||||
From within FreeCAD, run the following:
|
||||
import Test, TestDraftGui
|
||||
Test.runTestsFromModule(TestDraftGui)
|
||||
|
||||
For the non-GUI tests see TestDraft.
|
||||
"""
|
||||
|
||||
# ===========================================================================
|
||||
# The unit tests can be run from the operating system terminal, or from
|
||||
# within FreeCAD itself.
|
||||
#
|
||||
# The tests can be run using the full 'FreeCAD' executable
|
||||
# or the console only 'FreeCADCmd' executable. In the latter case
|
||||
# some functions cannot be tested as the view providers (visual properties)
|
||||
# are not available.
|
||||
#
|
||||
# ===========================================================================
|
||||
# In the following, first the command to run the test from the operating
|
||||
# system terminal is listed, followed by the commands to run the test
|
||||
# from the Python console within FreeCAD.
|
||||
#
|
||||
# ===========================================================================
|
||||
# Run all Draft tests
|
||||
# ----
|
||||
# FreeCAD -t TestDraft
|
||||
#
|
||||
# >>> import Test, TestDraft
|
||||
# >>> Test.runTestsFromModule(TestDraft)
|
||||
#
|
||||
# ===========================================================================
|
||||
# Run tests from a specific module (all classes within this module)
|
||||
# ----
|
||||
# FreeCAD -t drafttests.test_creation
|
||||
#
|
||||
# >>> import Test, drafttests.test_creation
|
||||
# >>> Test.runTestsFromModule(drafttests.test_creation)
|
||||
#
|
||||
# ===========================================================================
|
||||
# Run tests from a specific class within a module
|
||||
# ----
|
||||
# FreeCAD -t drafttests.test_creation.DraftCreation
|
||||
#
|
||||
# >>> import Test, drafttests.test_creation
|
||||
# >>> Test.runTestsFromClass(drafttests.test_creation.DraftCreation)
|
||||
#
|
||||
# ===========================================================================
|
||||
# Run a specific unit test from a class within a module
|
||||
# ----
|
||||
# FreeCAD -t drafttests.test_creation.DraftCreation.test_line
|
||||
#
|
||||
# >>> import unittest
|
||||
# >>> one_test = "drafttests.test_creation.DraftCreation.test_line"
|
||||
# >>> all_tests = unittest.TestLoader().loadTestsFromName(one_test)
|
||||
# >>> unittest.TextTestRunner().run(all_tests)
|
||||
|
||||
# ===========================================================================
|
||||
# When the full test is run
|
||||
# FreeCAD -t TestDraft
|
||||
#
|
||||
# all classes that are found in this file are run.
|
||||
#
|
||||
# We import the classes from submodules. These classes contain
|
||||
# the actual unit tests.
|
||||
#
|
||||
# The classes will be run in alphabetical order. So, to force
|
||||
# a particular order of testing we import them with a name
|
||||
# that follows a defined alphanumeric sequence.
|
||||
|
||||
# Import tests
|
||||
from drafttests.test_import_gui import DraftGuiImport as DraftTestGui01
|
||||
from drafttests.test_import_tools import DraftImportTools as DraftTestGui02
|
||||
from drafttests.test_pivy import DraftPivy as DraftTestGui03
|
||||
|
||||
# Use the modules so that code checkers don't complain (flake8)
|
||||
True if DraftTestGui01 else False
|
||||
True if DraftTestGui02 else False
|
||||
True if DraftTestGui03 else False
|
||||
+104
-61
@@ -1,20 +1,3 @@
|
||||
## @package WorkingPlane
|
||||
# \ingroup DRAFT
|
||||
# \brief This module handles the Working Plane and grid of the Draft module.
|
||||
#
|
||||
# This module provides the plane class which provides a virtual working plane
|
||||
# in FreeCAD and a couple of utility functions.
|
||||
"""@package WorkingPlane
|
||||
\ingroup DRAFT
|
||||
\brief This module handles the working plane and grid of the Draft Workbench.
|
||||
|
||||
This module provides the plane class which provides a virtual working plane
|
||||
in FreeCAD and a couple of utility functions.
|
||||
The working plane is mostly intended to be used in the Draft Workbench
|
||||
to draw 2D objects in various orientations, not only in the standard XY,
|
||||
YZ, and XZ planes.
|
||||
"""
|
||||
|
||||
# ***************************************************************************
|
||||
# * Copyright (c) 2009, 2010 Ken Cline <[email protected]> *
|
||||
# * *
|
||||
@@ -35,64 +18,87 @@ YZ, and XZ planes.
|
||||
# * USA *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
"""Provide the working plane code and utilities for the Draft Workbench.
|
||||
|
||||
This module provides the plane class which provides a virtual working plane
|
||||
in FreeCAD and a couple of utility functions.
|
||||
The working plane is mostly intended to be used in the Draft Workbench
|
||||
to draw 2D objects in various orientations, not only in the standard XY,
|
||||
YZ, and XZ planes.
|
||||
"""
|
||||
## @package WorkingPlane
|
||||
# \ingroup DRAFT
|
||||
# \brief This module handles the Working Plane and grid of the Draft module.
|
||||
#
|
||||
# This module provides the plane class which provides a virtual working plane
|
||||
# in FreeCAD and a couple of utility functions.
|
||||
|
||||
import FreeCAD, math, DraftVecUtils
|
||||
import math
|
||||
|
||||
import FreeCAD
|
||||
import DraftVecUtils
|
||||
from FreeCAD import Vector
|
||||
from FreeCAD import Console as FCC
|
||||
|
||||
__title__ = "FreeCAD Working Plane utility"
|
||||
__author__ = "Ken Cline"
|
||||
__url__ = "https://www.freecadweb.org"
|
||||
|
||||
|
||||
class plane:
|
||||
class Plane:
|
||||
"""A WorkPlane object.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
u: Base::Vector3, optional
|
||||
An axis (vector) that helps define the working plane.
|
||||
It defaults to `(1, 0, 0)`, or the +X axis.
|
||||
|
||||
v: Base::Vector3, optional
|
||||
An axis (vector) that helps define the working plane.
|
||||
It defaults to `(0, 1, 0)`, or the +Y axis.
|
||||
|
||||
w: Base::Vector3, optional
|
||||
An axis that is supposed to be perpendicular to `u` and `v`;
|
||||
it is redundant.
|
||||
It defaults to `(0, 0, 1)`, or the +Z axis.
|
||||
|
||||
pos: Base::Vector3, optional
|
||||
A point through which the plane goes through.
|
||||
It defaults to the origin `(0, 0, 0)`.
|
||||
|
||||
Attributes
|
||||
----------
|
||||
doc : App::Document
|
||||
doc: App::Document
|
||||
The active document. Reset view when `doc` changes.
|
||||
weak : bool
|
||||
|
||||
weak: bool
|
||||
It is `True` if the plane has been defined by `setup()`
|
||||
or has been reset. A weak plane can be changed
|
||||
(it is the "auto" mode), while a strong plane will keep
|
||||
its position until weakened (it is "locked")
|
||||
u : Base::Vector3
|
||||
|
||||
u: Base::Vector3
|
||||
An axis (vector) that helps define the working plane.
|
||||
v : Base::Vector3
|
||||
|
||||
v: Base::Vector3
|
||||
An axis (vector) that helps define the working plane.
|
||||
axis : Base::Vector3
|
||||
|
||||
axis: Base::Vector3
|
||||
A vector that is supposed to be perpendicular to `u` and `v`;
|
||||
it is helpful although redundant.
|
||||
position : Base::Vector3
|
||||
|
||||
position: Base::Vector3
|
||||
A point, which the plane goes through,
|
||||
that helps define the working plane.
|
||||
stored : bool
|
||||
|
||||
stored: bool
|
||||
A placeholder for a stored state.
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
u=Vector(1, 0, 0), v=Vector(0, 1, 0), w=Vector(0, 0, 1),
|
||||
pos=Vector(0, 0, 0)):
|
||||
"""Initialize the working plane.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
u : Base::Vector3, optional
|
||||
An axis (vector) that helps define the working plane.
|
||||
It defaults to `(1, 0, 0)`, or the +X axis.
|
||||
v : Base::Vector3, optional
|
||||
An axis (vector) that helps define the working plane.
|
||||
It defaults to `(0, 1, 0)`, or the +Y axis.
|
||||
w : Base::Vector3, optional
|
||||
An axis that is supposed to be perpendicular to `u` and `v`;
|
||||
it is redundant.
|
||||
It defaults to `(0, 0, 1)`, or the +Z axis.
|
||||
pos : Base::Vector3, optional
|
||||
A point through which the plane goes through.
|
||||
It defaults to the origin `(0, 0, 0)`.
|
||||
"""
|
||||
# keep track of active document. Reset view when doc changes.
|
||||
self.doc = None
|
||||
self.weak = True
|
||||
@@ -122,6 +128,7 @@ class plane:
|
||||
----------
|
||||
p : Base::Vector3
|
||||
The external point to consider.
|
||||
|
||||
direction : Base::Vector3, optional
|
||||
The unit vector that indicates the direction of the distance.
|
||||
|
||||
@@ -326,8 +333,8 @@ class plane:
|
||||
offsetVector.multiply(offset)
|
||||
self.position = point.add(offsetVector)
|
||||
self.weak = False
|
||||
# FCC.PrintMessage("(position = " + str(self.position) + ")\n")
|
||||
# FCC.PrintMessage(self.__repr__() + "\n")
|
||||
# Console.PrintMessage("(position = " + str(self.position) + ")\n")
|
||||
# Console.PrintMessage(self.__repr__() + "\n")
|
||||
|
||||
def alignToPointAndAxis_SVG(self, point, axis, offset=0):
|
||||
"""Align the working plane to a point and an axis (vector).
|
||||
@@ -436,14 +443,14 @@ class plane:
|
||||
|
||||
# spat_vec = self.u.cross(self.v)
|
||||
# spat_res = spat_vec.dot(axis)
|
||||
# FCC.PrintMessage(projcase + " spat Prod = " + str(spat_res) + "\n")
|
||||
# Console.PrintMessage(projcase + " spat Prod = " + str(spat_res) + "\n")
|
||||
|
||||
offsetVector = Vector(axis)
|
||||
offsetVector.multiply(offset)
|
||||
self.position = point.add(offsetVector)
|
||||
self.weak = False
|
||||
# FCC.PrintMessage("(position = " + str(self.position) + ")\n")
|
||||
# FCC.PrintMessage(self.__repr__() + "\n")
|
||||
# Console.PrintMessage("(position = " + str(self.position) + ")\n")
|
||||
# Console.PrintMessage(self.__repr__() + "\n")
|
||||
|
||||
def alignToCurve(self, shape, offset=0):
|
||||
"""Align plane to curve. NOT YET IMPLEMENTED.
|
||||
@@ -631,7 +638,7 @@ class plane:
|
||||
When the interface is not loaded it should fail and print
|
||||
a message, `FreeCAD.Console.PrintError()`.
|
||||
|
||||
See also
|
||||
See Also
|
||||
--------
|
||||
alignToFace, alignToCurve
|
||||
"""
|
||||
@@ -652,7 +659,7 @@ class plane:
|
||||
return False
|
||||
|
||||
def setup(self, direction=None, point=None, upvec=None, force=False):
|
||||
"""Setup the working plane if it exists but is undefined.
|
||||
"""Set up the working plane if it exists but is undefined.
|
||||
|
||||
If `direction` and `point` are present,
|
||||
it calls `alignToPointAndAxis(point, direction, 0, upvec)`.
|
||||
@@ -704,7 +711,7 @@ class plane:
|
||||
# perpendicular to the current view
|
||||
self.alignToPointAndAxis(Vector(0, 0, 0),
|
||||
vdir.negative(), 0, upvec)
|
||||
except:
|
||||
except Exception:
|
||||
pass
|
||||
if force:
|
||||
self.weak = False
|
||||
@@ -719,6 +726,39 @@ class plane:
|
||||
self.doc = None
|
||||
self.weak = True
|
||||
|
||||
def setTop(self):
|
||||
"""sets the WP to top position and updates the GUI"""
|
||||
self.alignToPointAndAxis(FreeCAD.Vector(0.0, 0.0, 0.0), FreeCAD.Vector(0, 0, 1), 0.0)
|
||||
if FreeCAD.GuiUp:
|
||||
import FreeCADGui
|
||||
from draftutils.translate import translate
|
||||
if hasattr(FreeCADGui,"Snapper"):
|
||||
FreeCADGui.Snapper.setGrid()
|
||||
if hasattr(FreeCADGui,"draftToolBar"):
|
||||
FreeCADGui.draftToolBar.wplabel.setText(translate("draft", "Top"))
|
||||
|
||||
def setFront(self):
|
||||
"""sets the WP to front position and updates the GUI"""
|
||||
self.alignToPointAndAxis(FreeCAD.Vector(0.0, 0.0, 0.0), FreeCAD.Vector(0, 1, 0), 0.0)
|
||||
if FreeCAD.GuiUp:
|
||||
import FreeCADGui
|
||||
from draftutils.translate import translate
|
||||
if hasattr(FreeCADGui,"Snapper"):
|
||||
FreeCADGui.Snapper.setGrid()
|
||||
if hasattr(FreeCADGui,"draftToolBar"):
|
||||
FreeCADGui.draftToolBar.wplabel.setText(translate("draft", "Front"))
|
||||
|
||||
def setSide(self):
|
||||
"""sets the WP to top position and updates the GUI"""
|
||||
self.alignToPointAndAxis(FreeCAD.Vector(0.0, 0.0, 0.0), FreeCAD.Vector(-1, 0, 0), 0.0)
|
||||
if FreeCAD.GuiUp:
|
||||
import FreeCADGui
|
||||
from draftutils.translate import translate
|
||||
if hasattr(FreeCADGui,"Snapper"):
|
||||
FreeCADGui.Snapper.setGrid()
|
||||
if hasattr(FreeCADGui,"draftToolBar"):
|
||||
FreeCADGui.draftToolBar.wplabel.setText(translate("draft", "Side"))
|
||||
|
||||
def getRotation(self):
|
||||
"""Return a placement describing the plane orientation only.
|
||||
|
||||
@@ -878,7 +918,7 @@ class plane:
|
||||
Base::Vector3
|
||||
The relative coordinates of the point from the plane.
|
||||
|
||||
See also
|
||||
See Also
|
||||
--------
|
||||
getGlobalCoords, getLocalRot, getGlobalRot
|
||||
|
||||
@@ -944,7 +984,7 @@ class plane:
|
||||
Base::Vector3
|
||||
The coordinates of the point from the absolute origin.
|
||||
|
||||
See also
|
||||
See Also
|
||||
--------
|
||||
getLocalCoords, getLocalRot, getGlobalRot
|
||||
|
||||
@@ -999,7 +1039,7 @@ class plane:
|
||||
The relative coordinates of the point from the plane,
|
||||
if the plane had its `position` at the global origin.
|
||||
|
||||
See also
|
||||
See Also
|
||||
--------
|
||||
getLocalCoords, getGlobalCoords, getGlobalRot
|
||||
"""
|
||||
@@ -1039,7 +1079,7 @@ class plane:
|
||||
Base::Vector3
|
||||
The coordinates of the point from the absolute origin.
|
||||
|
||||
See also
|
||||
See Also
|
||||
--------
|
||||
getGlobalCoords, getLocalCoords, getLocalRot
|
||||
"""
|
||||
@@ -1144,7 +1184,7 @@ class plane:
|
||||
Angle between the `u` vector, and a projected vector
|
||||
on the global horizontal plane.
|
||||
|
||||
See also
|
||||
See Also
|
||||
--------
|
||||
DraftVecUtils.angle
|
||||
"""
|
||||
@@ -1156,6 +1196,9 @@ class plane:
|
||||
return DraftVecUtils.angle(self.u, proj, norm)
|
||||
|
||||
|
||||
plane = Plane
|
||||
|
||||
|
||||
def getPlacementFromPoints(points):
|
||||
"""Return a placement from a list of 3 or 4 points.
|
||||
|
||||
@@ -1185,7 +1228,7 @@ def getPlacementFromPoints(points):
|
||||
defined by `points`,
|
||||
or `None` is it fails to use the points.
|
||||
|
||||
See also
|
||||
See Also
|
||||
--------
|
||||
getPlacement
|
||||
"""
|
||||
@@ -1198,7 +1241,7 @@ def getPlacementFromPoints(points):
|
||||
pl.axis = (points[3].sub(points[0]).normalize())
|
||||
else:
|
||||
pl.axis = ((pl.u).cross(pl.v)).normalize()
|
||||
except:
|
||||
except Exception:
|
||||
return None
|
||||
p = pl.getPlacement()
|
||||
del pl
|
||||
@@ -1229,14 +1272,14 @@ def getPlacementFromFace(face, rotated=False):
|
||||
defined by `face`,
|
||||
or `None` if it fails to use `face`.
|
||||
|
||||
See also
|
||||
See Also
|
||||
--------
|
||||
alignToFace, getPlacement
|
||||
"""
|
||||
pl = plane()
|
||||
try:
|
||||
pl.alignToFace(face)
|
||||
except:
|
||||
except Exception:
|
||||
return None
|
||||
p = pl.getPlacement(rotated)
|
||||
del pl
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
"""Commands that require the graphical user interface to work.
|
||||
|
||||
These GUI commands are called by buttons, menus, contextual menus,
|
||||
toolbars, or other ways that require graphical widgets.
|
||||
They are normally loaded in the workbench's `InitGui.py`.
|
||||
"""
|
||||
|
||||
@@ -1,8 +1,3 @@
|
||||
"""Provide the Draft ArrayTools command to group the other array tools."""
|
||||
## @package gui_arrays
|
||||
# \ingroup DRAFT
|
||||
# \brief Provide the Draft ArrayTools command to group the other array tools.
|
||||
|
||||
# ***************************************************************************
|
||||
# * (c) 2020 Eliud Cabrera Castillo <[email protected]> *
|
||||
# * *
|
||||
@@ -25,9 +20,14 @@
|
||||
# * USA *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
"""Provide the Draft ArrayTools command to group the other array tools."""
|
||||
## @package gui_arrays
|
||||
# \ingroup DRAFT
|
||||
# \brief Provide the Draft ArrayTools command to group the other array tools.
|
||||
from PySide.QtCore import QT_TRANSLATE_NOOP
|
||||
|
||||
import FreeCAD as App
|
||||
import FreeCADGui as Gui
|
||||
from PySide.QtCore import QT_TRANSLATE_NOOP
|
||||
|
||||
|
||||
class ArrayGroupCommand:
|
||||
@@ -49,8 +49,11 @@ class ArrayGroupCommand:
|
||||
'ToolTip': QT_TRANSLATE_NOOP("Arch", _tooltip)}
|
||||
|
||||
def IsActive(self):
|
||||
"""Be active only when a document is active."""
|
||||
return App.ActiveDocument is not None
|
||||
"""Return True when this command should be available."""
|
||||
if App.ActiveDocument:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
Gui.addCommand('Draft_ArrayTools', ArrayGroupCommand())
|
||||
|
||||
@@ -1,9 +1,3 @@
|
||||
"""This module provides the Base object for all Draft Gui commands.
|
||||
"""
|
||||
## @package gui_base
|
||||
# \ingroup DRAFT
|
||||
# \brief This module provides the Base object for all Draft Gui commands.
|
||||
|
||||
# ***************************************************************************
|
||||
# * (c) 2009 Yorik van Havre <[email protected]> *
|
||||
# * (c) 2010 Ken Cline <[email protected]> *
|
||||
@@ -28,10 +22,14 @@
|
||||
# * USA *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
"""Provide the Base object for all Draft Gui commands."""
|
||||
## @package gui_base
|
||||
# \ingroup DRAFT
|
||||
# \brief This module provides the Base object for all Draft Gui commands.
|
||||
|
||||
import FreeCAD as App
|
||||
import FreeCADGui as Gui
|
||||
import DraftGui
|
||||
import draftutils.todo as todo
|
||||
|
||||
|
||||
class GuiCommandBase:
|
||||
@@ -52,7 +50,7 @@ class GuiCommandBase:
|
||||
|
||||
Each string in the list of strings represents a Python instruction
|
||||
which will be executed in a delayed fashion
|
||||
by `DraftGui.todo.delayCommit()`
|
||||
by `todo.ToDo.delayCommit()`
|
||||
::
|
||||
list1 = ["a = FreeCAD.Vector()",
|
||||
"pl = FreeCAD.Placement()",
|
||||
@@ -69,6 +67,7 @@ class GuiCommandBase:
|
||||
>>> pl = FreeCAD.Placement()
|
||||
>>> Draft.autogroup(obj)
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.call = None
|
||||
self.commit_list = []
|
||||
@@ -78,7 +77,8 @@ class GuiCommandBase:
|
||||
self.planetrack = None
|
||||
|
||||
def IsActive(self):
|
||||
if Gui.ActiveDocument:
|
||||
"""Return True when this command should be available."""
|
||||
if App.ActiveDocument:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
@@ -102,7 +102,7 @@ class GuiCommandBase:
|
||||
pass
|
||||
self.call = None
|
||||
if self.commit_list:
|
||||
DraftGui.todo.delayCommit(self.commit_list)
|
||||
todo.ToDo.delayCommit(self.commit_list)
|
||||
self.commit_list = []
|
||||
|
||||
def commit(self, name, func):
|
||||
|
||||
@@ -1,9 +1,3 @@
|
||||
"""This module provides the Draft CircularArray tool.
|
||||
"""
|
||||
## @package gui_circulararray
|
||||
# \ingroup DRAFT
|
||||
# \brief This module provides the Draft CircularArray tool.
|
||||
|
||||
# ***************************************************************************
|
||||
# * (c) 2019 Eliud Cabrera Castillo <[email protected]> *
|
||||
# * *
|
||||
@@ -26,41 +20,28 @@
|
||||
# * USA *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
"""Provides the Draft CircularArray tool."""
|
||||
## @package gui_circulararray
|
||||
# \ingroup DRAFT
|
||||
# \brief This module provides the Draft CircularArray tool.
|
||||
|
||||
from pivy import coin
|
||||
from PySide.QtCore import QT_TRANSLATE_NOOP
|
||||
|
||||
import FreeCAD as App
|
||||
import FreeCADGui as Gui
|
||||
import Draft
|
||||
import DraftGui
|
||||
import Draft_rc
|
||||
from . import gui_base
|
||||
from draftguitools import gui_base
|
||||
from drafttaskpanels import task_circulararray
|
||||
import draftutils.todo as todo
|
||||
|
||||
|
||||
if App.GuiUp:
|
||||
from PySide.QtCore import QT_TRANSLATE_NOOP
|
||||
# import DraftTools
|
||||
from DraftGui import translate
|
||||
# from DraftGui import displayExternal
|
||||
from pivy import coin
|
||||
else:
|
||||
def QT_TRANSLATE_NOOP(context, text):
|
||||
return text
|
||||
|
||||
def translate(context, text):
|
||||
return text
|
||||
|
||||
|
||||
def _tr(text):
|
||||
"""Function to translate with the context set"""
|
||||
return translate("Draft", text)
|
||||
|
||||
|
||||
# So the resource file doesn't trigger errors from code checkers (flake8)
|
||||
# The module is used to prevent complaints from code checkers (flake8)
|
||||
True if Draft_rc.__name__ else False
|
||||
|
||||
|
||||
class GuiCommandCircularArray(gui_base.GuiCommandBase):
|
||||
"""Gui command for the CircularArray tool"""
|
||||
"""Gui command for the CircularArray tool."""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
@@ -74,6 +55,7 @@ class GuiCommandCircularArray(gui_base.GuiCommandBase):
|
||||
self.point = App.Vector()
|
||||
|
||||
def GetResources(self):
|
||||
"""Set icon, menu and tooltip."""
|
||||
_msg = ("Creates copies of a selected object, "
|
||||
"and places the copies in a circular pattern.\n"
|
||||
"The properties of the array can be further modified after "
|
||||
@@ -85,7 +67,7 @@ class GuiCommandCircularArray(gui_base.GuiCommandBase):
|
||||
return d
|
||||
|
||||
def Activated(self):
|
||||
"""This is called when the command is executed.
|
||||
"""Execute when the command is called.
|
||||
|
||||
We add callbacks that connect the 3D view with
|
||||
the widgets of the task panel.
|
||||
@@ -103,10 +85,10 @@ class GuiCommandCircularArray(gui_base.GuiCommandBase):
|
||||
# of the interface, to be able to call a function from within it.
|
||||
self.ui.source_command = self
|
||||
# Gui.Control.showDialog(self.ui)
|
||||
DraftGui.todo.delay(Gui.Control.showDialog, self.ui)
|
||||
todo.ToDo.delay(Gui.Control.showDialog, self.ui)
|
||||
|
||||
def move(self, event_cb):
|
||||
"""This is a callback for when the mouse pointer moves in the 3D view.
|
||||
"""Execute as a callback when the pointer moves in the 3D view.
|
||||
|
||||
It should automatically update the coordinates in the widgets
|
||||
of the task panel.
|
||||
@@ -119,7 +101,7 @@ class GuiCommandCircularArray(gui_base.GuiCommandBase):
|
||||
self.ui.display_point(self.point)
|
||||
|
||||
def click(self, event_cb=None):
|
||||
"""This is a callback for when the mouse pointer clicks on the 3D view.
|
||||
"""Execute as a callback when the pointer clicks on the 3D view.
|
||||
|
||||
It should act as if the Enter key was pressed, or the OK button
|
||||
was pressed in the task panel.
|
||||
@@ -136,7 +118,7 @@ class GuiCommandCircularArray(gui_base.GuiCommandBase):
|
||||
self.ui.accept()
|
||||
|
||||
def completed(self):
|
||||
"""This is called when the command is terminated.
|
||||
"""Execute when the command is terminated.
|
||||
|
||||
We should remove the callbacks that were added to the 3D view
|
||||
and then close the task panel.
|
||||
@@ -146,10 +128,8 @@ class GuiCommandCircularArray(gui_base.GuiCommandBase):
|
||||
self.view.removeEventCallbackPivy(self.mouse_event,
|
||||
self.callback_click)
|
||||
if Gui.Control.activeDialog():
|
||||
Gui.Snapper.off()
|
||||
Gui.Control.closeDialog()
|
||||
super().finish()
|
||||
|
||||
|
||||
if App.GuiUp:
|
||||
Gui.addCommand('Draft_CircularArray', GuiCommandCircularArray())
|
||||
Gui.addCommand('Draft_CircularArray', GuiCommandCircularArray())
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,8 +1,3 @@
|
||||
"""Provide the Draft OrthoArray tool."""
|
||||
## @package gui_orthoarray
|
||||
# \ingroup DRAFT
|
||||
# \brief Provide the Draft OrthoArray tool.
|
||||
|
||||
# ***************************************************************************
|
||||
# * (c) 2020 Eliud Cabrera Castillo <[email protected]> *
|
||||
# * *
|
||||
@@ -25,36 +20,23 @@
|
||||
# * USA *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
"""Provides the Draft OrthoArray GuiCommand."""
|
||||
## @package gui_orthoarray
|
||||
# \ingroup DRAFT
|
||||
# \brief Provides the Draft OrthoArray GuiCommand.
|
||||
|
||||
from pivy import coin
|
||||
from PySide.QtCore import QT_TRANSLATE_NOOP
|
||||
|
||||
import FreeCAD as App
|
||||
import FreeCADGui as Gui
|
||||
import Draft
|
||||
import DraftGui
|
||||
import Draft_rc
|
||||
from . import gui_base
|
||||
from draftguitools import gui_base
|
||||
from drafttaskpanels import task_orthoarray
|
||||
import draftutils.todo as todo
|
||||
|
||||
|
||||
if App.GuiUp:
|
||||
from PySide.QtCore import QT_TRANSLATE_NOOP
|
||||
# import DraftTools
|
||||
from draftutils.translate import translate
|
||||
# from DraftGui import displayExternal
|
||||
from pivy import coin
|
||||
else:
|
||||
def QT_TRANSLATE_NOOP(context, text):
|
||||
return text
|
||||
|
||||
def translate(context, text):
|
||||
return text
|
||||
|
||||
|
||||
def _tr(text):
|
||||
"""Translate the text with the context set."""
|
||||
return translate("Draft", text)
|
||||
|
||||
|
||||
# So the resource file doesn't trigger errors from code checkers (flake8)
|
||||
# The module is used to prevent complaints from code checkers (flake8)
|
||||
True if Draft_rc.__name__ else False
|
||||
|
||||
|
||||
@@ -85,7 +67,7 @@ class GuiCommandOrthoArray(gui_base.GuiCommandBase):
|
||||
return d
|
||||
|
||||
def Activated(self):
|
||||
"""Execute this when the command is called.
|
||||
"""Execute when the command is called.
|
||||
|
||||
We add callbacks that connect the 3D view with
|
||||
the widgets of the task panel.
|
||||
@@ -103,10 +85,10 @@ class GuiCommandOrthoArray(gui_base.GuiCommandBase):
|
||||
# of the interface, to be able to call a function from within it.
|
||||
self.ui.source_command = self
|
||||
# Gui.Control.showDialog(self.ui)
|
||||
DraftGui.todo.delay(Gui.Control.showDialog, self.ui)
|
||||
todo.ToDo.delay(Gui.Control.showDialog, self.ui)
|
||||
|
||||
def click(self, event_cb=None):
|
||||
"""Run callback for when the mouse pointer clicks on the 3D view.
|
||||
"""Execute as a callback when the pointer clicks on the 3D view.
|
||||
|
||||
It should act as if the Enter key was pressed, or the OK button
|
||||
was pressed in the task panel.
|
||||
@@ -123,7 +105,7 @@ class GuiCommandOrthoArray(gui_base.GuiCommandBase):
|
||||
self.ui.accept()
|
||||
|
||||
def completed(self):
|
||||
"""Run when the command is terminated.
|
||||
"""Execute when the command is terminated.
|
||||
|
||||
We should remove the callbacks that were added to the 3D view
|
||||
and then close the task panel.
|
||||
@@ -133,10 +115,8 @@ class GuiCommandOrthoArray(gui_base.GuiCommandBase):
|
||||
self.view.removeEventCallbackPivy(self.mouse_event,
|
||||
self.callback_click)
|
||||
if Gui.Control.activeDialog():
|
||||
Gui.Snapper.off()
|
||||
Gui.Control.closeDialog()
|
||||
super().finish()
|
||||
|
||||
|
||||
if App.GuiUp:
|
||||
Gui.addCommand('Draft_OrthoArray', GuiCommandOrthoArray())
|
||||
Gui.addCommand('Draft_OrthoArray', GuiCommandOrthoArray())
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
# ***************************************************************************
|
||||
# * Copyright (c) 2019 Yorik van Havre <[email protected]> *
|
||||
# * *
|
||||
# * This program is free software; you can redistribute it and/or modify *
|
||||
# * it under the terms of the GNU Lesser General Public License (LGPL) *
|
||||
# * as published by the Free Software Foundation; either version 2 of *
|
||||
# * the License, or (at your option) any later version. *
|
||||
# * for detail see the LICENCE text file. *
|
||||
# * *
|
||||
# * This program is distributed in the hope that it will be useful, *
|
||||
# * but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
# * GNU Library General Public License for more details. *
|
||||
# * *
|
||||
# * You should have received a copy of the GNU Library General Public *
|
||||
# * License along with this program; if not, write to the Free Software *
|
||||
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
||||
# * USA *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
"""Provides the Draft WorkingPlaneProxy tool."""
|
||||
## @package gui_planeproxy
|
||||
# \ingroup DRAFT
|
||||
# \brief This module provides the Draft WorkingPlaneProxy tool.
|
||||
|
||||
from PySide.QtCore import QT_TRANSLATE_NOOP
|
||||
|
||||
import FreeCAD as App
|
||||
import FreeCADGui as Gui
|
||||
import Draft_rc
|
||||
|
||||
# The module is used to prevent complaints from code checkers (flake8)
|
||||
True if Draft_rc.__name__ else False
|
||||
|
||||
__title__ = "FreeCAD Draft Workbench GUI Tools - Working plane-related tools"
|
||||
__author__ = ("Yorik van Havre, Werner Mayer, Martin Burbaum, Ken Cline, "
|
||||
"Dmitry Chigrin")
|
||||
__url__ = "https://www.freecadweb.org"
|
||||
|
||||
|
||||
class Draft_WorkingPlaneProxy:
|
||||
"""The Draft_WorkingPlaneProxy command definition."""
|
||||
|
||||
def GetResources(self):
|
||||
"""Set icon, menu and tooltip."""
|
||||
_menu = "Create working plane proxy"
|
||||
_tip = ("Creates a proxy object from the current working plane.\n"
|
||||
"Once the object is created double click it in the tree view "
|
||||
"to restore the camera position and objects' visibilities.\n"
|
||||
"Then you can use it to save a different camera position "
|
||||
"and objects' states any time you need.")
|
||||
d = {'Pixmap': 'Draft_PlaneProxy',
|
||||
'MenuText': QT_TRANSLATE_NOOP("Draft_SetWorkingPlaneProxy",
|
||||
_menu),
|
||||
'ToolTip': QT_TRANSLATE_NOOP("Draft_SetWorkingPlaneProxy",
|
||||
_tip)}
|
||||
return d
|
||||
|
||||
def IsActive(self):
|
||||
"""Return True when this command should be available."""
|
||||
if Gui.ActiveDocument:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def Activated(self):
|
||||
"""Execute when the command is called."""
|
||||
if hasattr(App, "DraftWorkingPlane"):
|
||||
App.ActiveDocument.openTransaction("Create WP proxy")
|
||||
Gui.addModule("Draft")
|
||||
_cmd = "Draft.makeWorkingPlaneProxy("
|
||||
_cmd += "FreeCAD.DraftWorkingPlane.getPlacement()"
|
||||
_cmd += ")"
|
||||
Gui.doCommand(_cmd)
|
||||
App.ActiveDocument.commitTransaction()
|
||||
App.ActiveDocument.recompute()
|
||||
|
||||
|
||||
Gui.addCommand('Draft_WorkingPlaneProxy', Draft_WorkingPlaneProxy())
|
||||
@@ -1,9 +1,3 @@
|
||||
"""This module provides the Draft PolarArray tool.
|
||||
"""
|
||||
## @package gui_polararray
|
||||
# \ingroup DRAFT
|
||||
# \brief This module provides the Draft PolarArray tool.
|
||||
|
||||
# ***************************************************************************
|
||||
# * (c) 2019 Eliud Cabrera Castillo <[email protected]> *
|
||||
# * *
|
||||
@@ -26,41 +20,28 @@
|
||||
# * USA *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
"""Provides the Draft PolarArray tool."""
|
||||
## @package gui_polararray
|
||||
# \ingroup DRAFT
|
||||
# \brief This module provides the Draft PolarArray tool.
|
||||
|
||||
from pivy import coin
|
||||
from PySide.QtCore import QT_TRANSLATE_NOOP
|
||||
|
||||
import FreeCAD as App
|
||||
import FreeCADGui as Gui
|
||||
import Draft
|
||||
import DraftGui
|
||||
import Draft_rc
|
||||
from . import gui_base
|
||||
from draftguitools import gui_base
|
||||
from drafttaskpanels import task_polararray
|
||||
import draftutils.todo as todo
|
||||
|
||||
|
||||
if App.GuiUp:
|
||||
from PySide.QtCore import QT_TRANSLATE_NOOP
|
||||
# import DraftTools
|
||||
from DraftGui import translate
|
||||
# from DraftGui import displayExternal
|
||||
from pivy import coin
|
||||
else:
|
||||
def QT_TRANSLATE_NOOP(context, text):
|
||||
return text
|
||||
|
||||
def translate(context, text):
|
||||
return text
|
||||
|
||||
|
||||
def _tr(text):
|
||||
"""Function to translate with the context set"""
|
||||
return translate("Draft", text)
|
||||
|
||||
|
||||
# So the resource file doesn't trigger errors from code checkers (flake8)
|
||||
# The module is used to prevent complaints from code checkers (flake8)
|
||||
True if Draft_rc.__name__ else False
|
||||
|
||||
|
||||
class GuiCommandPolarArray(gui_base.GuiCommandBase):
|
||||
"""Gui command for the PolarArray tool"""
|
||||
"""Gui command for the PolarArray tool."""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
@@ -74,6 +55,7 @@ class GuiCommandPolarArray(gui_base.GuiCommandBase):
|
||||
self.point = App.Vector()
|
||||
|
||||
def GetResources(self):
|
||||
"""Set icon, menu and tooltip."""
|
||||
_msg = ("Creates copies of a selected object, "
|
||||
"and places the copies in a polar pattern.\n"
|
||||
"The properties of the array can be further modified after "
|
||||
@@ -85,7 +67,7 @@ class GuiCommandPolarArray(gui_base.GuiCommandBase):
|
||||
return d
|
||||
|
||||
def Activated(self):
|
||||
"""This is called when the command is executed.
|
||||
"""Execute when the command is called.
|
||||
|
||||
We add callbacks that connect the 3D view with
|
||||
the widgets of the task panel.
|
||||
@@ -103,10 +85,10 @@ class GuiCommandPolarArray(gui_base.GuiCommandBase):
|
||||
# of the interface, to be able to call a function from within it.
|
||||
self.ui.source_command = self
|
||||
# Gui.Control.showDialog(self.ui)
|
||||
DraftGui.todo.delay(Gui.Control.showDialog, self.ui)
|
||||
todo.ToDo.delay(Gui.Control.showDialog, self.ui)
|
||||
|
||||
def move(self, event_cb):
|
||||
"""This is a callback for when the mouse pointer moves in the 3D view.
|
||||
"""Execute as a callback when the pointer moves in the 3D view.
|
||||
|
||||
It should automatically update the coordinates in the widgets
|
||||
of the task panel.
|
||||
@@ -119,7 +101,7 @@ class GuiCommandPolarArray(gui_base.GuiCommandBase):
|
||||
self.ui.display_point(self.point)
|
||||
|
||||
def click(self, event_cb=None):
|
||||
"""This is a callback for when the mouse pointer clicks on the 3D view.
|
||||
"""Execute as a callback when the pointer clicks on the 3D view.
|
||||
|
||||
It should act as if the Enter key was pressed, or the OK button
|
||||
was pressed in the task panel.
|
||||
@@ -136,7 +118,7 @@ class GuiCommandPolarArray(gui_base.GuiCommandBase):
|
||||
self.ui.accept()
|
||||
|
||||
def completed(self):
|
||||
"""This is called when the command is terminated.
|
||||
"""Execute when the command is terminated.
|
||||
|
||||
We should remove the callbacks that were added to the 3D view
|
||||
and then close the task panel.
|
||||
@@ -146,10 +128,8 @@ class GuiCommandPolarArray(gui_base.GuiCommandBase):
|
||||
self.view.removeEventCallbackPivy(self.mouse_event,
|
||||
self.callback_click)
|
||||
if Gui.Control.activeDialog():
|
||||
Gui.Snapper.off()
|
||||
Gui.Control.closeDialog()
|
||||
super().finish()
|
||||
|
||||
|
||||
if App.GuiUp:
|
||||
Gui.addCommand('Draft_PolarArray', GuiCommandPolarArray())
|
||||
Gui.addCommand('Draft_PolarArray', GuiCommandPolarArray())
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
# -*- coding: utf8 -*-
|
||||
# ***************************************************************************
|
||||
# * Copyright (c) 2019 Yorik van Havre <[email protected]> *
|
||||
# * *
|
||||
@@ -19,23 +18,33 @@
|
||||
# * USA *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
"""Provides the Draft SelectPlane tool."""
|
||||
## @package gui_selectplane
|
||||
# \ingroup DRAFT
|
||||
# \brief This module provides the Draft SelectPlane tool.
|
||||
|
||||
__title__ = "FreeCAD Draft Workbench GUI Tools - Working plane-related tools"
|
||||
__author__ = "Yorik van Havre, Werner Mayer, Martin Burbaum, Ken Cline, Dmitry Chigrin"
|
||||
__url__ = "https://www.freecadweb.org"
|
||||
|
||||
import math
|
||||
from pivy import coin
|
||||
from PySide import QtGui
|
||||
from PySide.QtCore import QT_TRANSLATE_NOOP
|
||||
|
||||
import FreeCAD
|
||||
import FreeCADGui
|
||||
import math
|
||||
import Draft
|
||||
import Draft_rc
|
||||
import DraftVecUtils
|
||||
import drafttaskpanels.task_selectplane as task_selectplane
|
||||
from draftutils.todo import todo
|
||||
from draftutils.messages import _msg
|
||||
from draftutils.translate import translate
|
||||
|
||||
# The module is used to prevent complaints from code checkers (flake8)
|
||||
True if Draft_rc.__name__ else False
|
||||
|
||||
def QT_TRANSLATE_NOOP(ctx,txt): return txt
|
||||
|
||||
__title__ = "FreeCAD Draft Workbench GUI Tools - Working plane-related tools"
|
||||
__author__ = ("Yorik van Havre, Werner Mayer, Martin Burbaum, Ken Cline, "
|
||||
"Dmitry Chigrin")
|
||||
__url__ = "https://www.freecadweb.org"
|
||||
|
||||
|
||||
class Draft_SelectPlane:
|
||||
@@ -48,10 +57,15 @@ class Draft_SelectPlane:
|
||||
|
||||
def GetResources(self):
|
||||
"""Set icon, menu and tooltip."""
|
||||
return {'Pixmap' : 'Draft_SelectPlane',
|
||||
'Accel' : "W, P",
|
||||
'MenuText': QT_TRANSLATE_NOOP("Draft_SelectPlane", "SelectPlane"),
|
||||
'ToolTip' : QT_TRANSLATE_NOOP("Draft_SelectPlane", "Select a working plane for geometry creation")}
|
||||
_msg = ("Select the face of solid body to create a working plane "
|
||||
"on which to sketch Draft objects.\n"
|
||||
"You may also select a three vertices or "
|
||||
"a Working Plane Proxy.")
|
||||
d = {'Pixmap': 'Draft_SelectPlane',
|
||||
'Accel': "W, P",
|
||||
'MenuText': QT_TRANSLATE_NOOP("Draft_SelectPlane", "SelectPlane"),
|
||||
'ToolTip': QT_TRANSLATE_NOOP("Draft_SelectPlane", _msg)}
|
||||
return d
|
||||
|
||||
def IsActive(self):
|
||||
"""Return True when this command should be available."""
|
||||
@@ -61,34 +75,33 @@ class Draft_SelectPlane:
|
||||
return False
|
||||
|
||||
def Activated(self):
|
||||
"""Execute this when the command is called."""
|
||||
# reset variables
|
||||
"""Execute when the command is called."""
|
||||
# Reset variables
|
||||
self.view = Draft.get3DView()
|
||||
self.wpButton = FreeCADGui.draftToolBar.wplabel
|
||||
FreeCAD.DraftWorkingPlane.setup()
|
||||
|
||||
# write current WP if states are empty
|
||||
# Write current WP if states are empty
|
||||
if not self.states:
|
||||
p = FreeCAD.DraftWorkingPlane
|
||||
self.states.append([p.u, p.v, p.axis, p.position])
|
||||
|
||||
m = translate("draft", "Pick a face, 3 vertices or a WP Proxy to define the drawing plane")
|
||||
FreeCAD.Console.PrintMessage(m+"\n")
|
||||
m = translate("draft", "Pick a face, 3 vertices "
|
||||
"or a WP Proxy to define the drawing plane")
|
||||
_msg(m)
|
||||
|
||||
from PySide import QtCore,QtGui
|
||||
|
||||
# create UI panel
|
||||
# Create task panel
|
||||
FreeCADGui.Control.closeDialog()
|
||||
self.taskd = SelectPlane_TaskPanel()
|
||||
self.taskd = task_selectplane.SelectPlaneTaskPanel()
|
||||
|
||||
# fill values
|
||||
self.taskd.form.checkCenter.setChecked(self.param.GetBool("CenterPlaneOnView",False))
|
||||
q = FreeCAD.Units.Quantity(self.param.GetFloat("gridSpacing",1.0),FreeCAD.Units.Length)
|
||||
# Fill values
|
||||
self.taskd.form.checkCenter.setChecked(self.param.GetBool("CenterPlaneOnView", False))
|
||||
q = FreeCAD.Units.Quantity(self.param.GetFloat("gridSpacing", 1.0), FreeCAD.Units.Length)
|
||||
self.taskd.form.fieldGridSpacing.setText(q.UserString)
|
||||
self.taskd.form.fieldGridMainLine.setValue(self.param.GetInt("gridEvery",10))
|
||||
self.taskd.form.fieldSnapRadius.setValue(self.param.GetInt("snapRange",8))
|
||||
self.taskd.form.fieldGridMainLine.setValue(self.param.GetInt("gridEvery", 10))
|
||||
self.taskd.form.fieldSnapRadius.setValue(self.param.GetInt("snapRange", 8))
|
||||
|
||||
# set icons
|
||||
# Set icons
|
||||
self.taskd.form.setWindowIcon(QtGui.QIcon(":/icons/Draft_SelectPlane.svg"))
|
||||
self.taskd.form.buttonTop.setIcon(QtGui.QIcon(":/icons/view-top.svg"))
|
||||
self.taskd.form.buttonFront.setIcon(QtGui.QIcon(":/icons/view-front.svg"))
|
||||
@@ -99,7 +112,7 @@ class Draft_SelectPlane:
|
||||
self.taskd.form.buttonCenter.setIcon(QtGui.QIcon(":/icons/view-fullscreen.svg"))
|
||||
self.taskd.form.buttonPrevious.setIcon(QtGui.QIcon(":/icons/edit-undo.svg"))
|
||||
|
||||
# connect slots
|
||||
# Connect slots
|
||||
self.taskd.form.buttonTop.clicked.connect(self.onClickTop)
|
||||
self.taskd.form.buttonFront.clicked.connect(self.onClickFront)
|
||||
self.taskd.form.buttonSide.clicked.connect(self.onClickSide)
|
||||
@@ -112,57 +125,59 @@ class Draft_SelectPlane:
|
||||
self.taskd.form.fieldGridMainLine.valueChanged.connect(self.onSetMainline)
|
||||
self.taskd.form.fieldSnapRadius.valueChanged.connect(self.onSetSnapRadius)
|
||||
|
||||
# try to find a WP from the current selection
|
||||
# Try to find a WP from the current selection
|
||||
if self.handle():
|
||||
return
|
||||
|
||||
# try other method
|
||||
# Try another method
|
||||
if FreeCAD.DraftWorkingPlane.alignToSelection():
|
||||
FreeCADGui.Selection.clearSelection()
|
||||
self.display(FreeCAD.DraftWorkingPlane.axis)
|
||||
self.finish()
|
||||
return
|
||||
|
||||
# rock 'n roll!
|
||||
|
||||
# Execute the actual task panel
|
||||
FreeCADGui.Control.showDialog(self.taskd)
|
||||
self.call = self.view.addEventCallback("SoEvent", self.action)
|
||||
|
||||
def finish(self,close=False):
|
||||
def finish(self, close=False):
|
||||
"""Execute when the command is terminated."""
|
||||
# Store values
|
||||
self.param.SetBool("CenterPlaneOnView",
|
||||
self.taskd.form.checkCenter.isChecked())
|
||||
|
||||
# store values
|
||||
self.param.SetBool("CenterPlaneOnView",self.taskd.form.checkCenter.isChecked())
|
||||
|
||||
# terminate coin callbacks
|
||||
# Terminate coin callbacks
|
||||
if self.call:
|
||||
try:
|
||||
self.view.removeEventCallback("SoEvent",self.call)
|
||||
self.view.removeEventCallback("SoEvent", self.call)
|
||||
except RuntimeError:
|
||||
# the view has been deleted already
|
||||
# The view has been deleted already
|
||||
pass
|
||||
self.call = None
|
||||
|
||||
# reset everything else
|
||||
# Reset everything else
|
||||
FreeCADGui.Control.closeDialog()
|
||||
FreeCAD.DraftWorkingPlane.restore()
|
||||
FreeCADGui.ActiveDocument.resetEdit()
|
||||
return True
|
||||
|
||||
def reject(self):
|
||||
|
||||
"""Execute when clicking the Cancel button."""
|
||||
self.finish()
|
||||
return True
|
||||
|
||||
def action(self, arg):
|
||||
|
||||
"""Set the callbacks for the view."""
|
||||
if arg["Type"] == "SoKeyboardEvent" and arg["Key"] == "ESCAPE":
|
||||
self.finish()
|
||||
if arg["Type"] == "SoMouseButtonEvent":
|
||||
if (arg["State"] == "DOWN") and (arg["Button"] == "BUTTON1"):
|
||||
# coin detection happens before the selection got a chance of being updated, so we must delay
|
||||
todo.delay(self.checkSelection,None)
|
||||
# Coin detection happens before the selection
|
||||
# got a chance of being updated, so we must delay
|
||||
todo.delay(self.checkSelection, None)
|
||||
|
||||
def checkSelection(self):
|
||||
|
||||
"""Check the selection, if there is a handle, finish the command."""
|
||||
if self.handle():
|
||||
self.finish()
|
||||
|
||||
@@ -175,18 +190,19 @@ class Draft_SelectPlane:
|
||||
FreeCAD.DraftWorkingPlane.alignToEdges(sel.Object.Shape.Edges)
|
||||
self.display(FreeCAD.DraftWorkingPlane.axis)
|
||||
return True
|
||||
elif Draft.getType(sel.Object) in ["WorkingPlaneProxy","BuildingPart"]:
|
||||
FreeCAD.DraftWorkingPlane.setFromPlacement(sel.Object.Placement,rebase=True)
|
||||
elif Draft.getType(sel.Object) in ("WorkingPlaneProxy",
|
||||
"BuildingPart"):
|
||||
FreeCAD.DraftWorkingPlane.setFromPlacement(sel.Object.Placement, rebase=True)
|
||||
FreeCAD.DraftWorkingPlane.weak = False
|
||||
if hasattr(sel.Object.ViewObject,"AutoWorkingPlane"):
|
||||
if hasattr(sel.Object.ViewObject, "AutoWorkingPlane"):
|
||||
if sel.Object.ViewObject.AutoWorkingPlane:
|
||||
FreeCAD.DraftWorkingPlane.weak = True
|
||||
if hasattr(sel.Object.ViewObject,"CutView") and hasattr(sel.Object.ViewObject,"AutoCutView"):
|
||||
if hasattr(sel.Object.ViewObject, "CutView") and hasattr(sel.Object.ViewObject, "AutoCutView"):
|
||||
if sel.Object.ViewObject.AutoCutView:
|
||||
sel.Object.ViewObject.CutView = True
|
||||
if hasattr(sel.Object.ViewObject,"RestoreView"):
|
||||
if hasattr(sel.Object.ViewObject, "RestoreView"):
|
||||
if sel.Object.ViewObject.RestoreView:
|
||||
if hasattr(sel.Object.ViewObject,"ViewData"):
|
||||
if hasattr(sel.Object.ViewObject, "ViewData"):
|
||||
if len(sel.Object.ViewObject.ViewData) >= 12:
|
||||
d = sel.Object.ViewObject.ViewData
|
||||
camtype = "orthographic"
|
||||
@@ -194,16 +210,15 @@ class Draft_SelectPlane:
|
||||
if d[12] == 1:
|
||||
camtype = "perspective"
|
||||
c = FreeCADGui.ActiveDocument.ActiveView.getCameraNode()
|
||||
from pivy import coin
|
||||
if isinstance(c,coin.SoOrthographicCamera):
|
||||
if isinstance(c, coin.SoOrthographicCamera):
|
||||
if camtype == "perspective":
|
||||
FreeCADGui.ActiveDocument.ActiveView.setCameraType("Perspective")
|
||||
elif isinstance(c,coin.SoPerspectiveCamera):
|
||||
elif isinstance(c, coin.SoPerspectiveCamera):
|
||||
if camtype == "orthographic":
|
||||
FreeCADGui.ActiveDocument.ActiveView.setCameraType("Orthographic")
|
||||
c = FreeCADGui.ActiveDocument.ActiveView.getCameraNode()
|
||||
c.position.setValue([d[0],d[1],d[2]])
|
||||
c.orientation.setValue([d[3],d[4],d[5],d[6]])
|
||||
c.position.setValue([d[0], d[1], d[2]])
|
||||
c.orientation.setValue([d[3], d[4], d[5], d[6]])
|
||||
c.nearDistance.setValue(d[7])
|
||||
c.farDistance.setValue(d[8])
|
||||
c.aspectRatio.setValue(d[9])
|
||||
@@ -212,9 +227,9 @@ class Draft_SelectPlane:
|
||||
c.height.setValue(d[11])
|
||||
else:
|
||||
c.heightAngle.setValue(d[11])
|
||||
if hasattr(sel.Object.ViewObject,"RestoreState"):
|
||||
if hasattr(sel.Object.ViewObject, "RestoreState"):
|
||||
if sel.Object.ViewObject.RestoreState:
|
||||
if hasattr(sel.Object.ViewObject,"VisibilityMap"):
|
||||
if hasattr(sel.Object.ViewObject, "VisibilityMap"):
|
||||
if sel.Object.ViewObject.VisibilityMap:
|
||||
for k,v in sel.Object.ViewObject.VisibilityMap.items():
|
||||
o = FreeCADGui.ActiveDocument.getObject(k)
|
||||
@@ -226,7 +241,7 @@ class Draft_SelectPlane:
|
||||
self.wpButton.setToolTip(translate("draft", "Current working plane")+": "+self.wpButton.text())
|
||||
return True
|
||||
elif Draft.getType(sel.Object) == "SectionPlane":
|
||||
FreeCAD.DraftWorkingPlane.setFromPlacement(sel.Object.Placement,rebase=True)
|
||||
FreeCAD.DraftWorkingPlane.setFromPlacement(sel.Object.Placement, rebase=True)
|
||||
FreeCAD.DraftWorkingPlane.weak = False
|
||||
self.display(FreeCAD.DraftWorkingPlane.axis)
|
||||
self.wpButton.setText(sel.Object.Label)
|
||||
@@ -239,7 +254,7 @@ class Draft_SelectPlane:
|
||||
self.display(FreeCAD.DraftWorkingPlane.axis)
|
||||
return True
|
||||
elif sel.SubElementNames[0] == "Plane":
|
||||
FreeCAD.DraftWorkingPlane.setFromPlacement(sel.Object.Placement,rebase=True)
|
||||
FreeCAD.DraftWorkingPlane.setFromPlacement(sel.Object.Placement, rebase=True)
|
||||
self.display(FreeCAD.DraftWorkingPlane.axis)
|
||||
return True
|
||||
elif len(sel.SubElementNames) == 3:
|
||||
@@ -263,7 +278,7 @@ class Draft_SelectPlane:
|
||||
import Part
|
||||
for s in sel:
|
||||
for so in s.SubObjects:
|
||||
if isinstance(so,Part.Vertex):
|
||||
if isinstance(so, Part.Vertex):
|
||||
subs.append(so)
|
||||
if len(subs) == 3:
|
||||
FreeCAD.DraftWorkingPlane.alignTo3Points(subs[0].Point,
|
||||
@@ -275,25 +290,31 @@ class Draft_SelectPlane:
|
||||
return False
|
||||
|
||||
def getCenterPoint(self, x, y, z):
|
||||
|
||||
"""Get the center point."""
|
||||
if not self.taskd.form.checkCenter.isChecked():
|
||||
return FreeCAD.Vector()
|
||||
v = FreeCAD.Vector(x,y,z)
|
||||
cam1 = FreeCAD.Vector(FreeCADGui.ActiveDocument.ActiveView.getCameraNode().position.getValue().getValue())
|
||||
v = FreeCAD.Vector(x, y, z)
|
||||
view = FreeCADGui.ActiveDocument.ActiveView
|
||||
camera = view.getCameraNode()
|
||||
cam1 = FreeCAD.Vector(camera.position.getValue().getValue())
|
||||
cam2 = FreeCADGui.ActiveDocument.ActiveView.getViewDirection()
|
||||
vcam1 = DraftVecUtils.project(cam1,v)
|
||||
vcam1 = DraftVecUtils.project(cam1, v)
|
||||
a = vcam1.getAngle(cam2)
|
||||
if a < 0.0001:
|
||||
return FreeCAD.Vector()
|
||||
d = vcam1.Length
|
||||
L = d/math.cos(a)
|
||||
vcam2 = DraftVecUtils.scaleTo(cam2,L)
|
||||
vcam2 = DraftVecUtils.scaleTo(cam2, L)
|
||||
cp = cam1.add(vcam2)
|
||||
return cp
|
||||
|
||||
def tostr(self, v):
|
||||
"""Make a string from a vector or tuple."""
|
||||
return "FreeCAD.Vector("+str(v[0])+","+str(v[1])+","+str(v[2])+")"
|
||||
string = "FreeCAD.Vector("
|
||||
string += str(v[0]) + ", "
|
||||
string += str(v[1]) + ", "
|
||||
string += str(v[2]) + ")"
|
||||
return string
|
||||
|
||||
def getOffset(self):
|
||||
"""Return the offset value as a float in mm."""
|
||||
@@ -305,48 +326,66 @@ class Draft_SelectPlane:
|
||||
return o
|
||||
|
||||
def onClickTop(self):
|
||||
|
||||
o = str(self.getOffset())
|
||||
FreeCADGui.doCommandGui(self.ac+"("+self.tostr(self.getCenterPoint(0,0,1))+","+self.tostr((0,0,1))+","+o+")")
|
||||
"""Execute when pressing the top button."""
|
||||
offset = str(self.getOffset())
|
||||
_cmd = self.ac
|
||||
_cmd += "("
|
||||
_cmd += self.tostr(self.getCenterPoint(0, 0, 1)) + ", "
|
||||
_cmd += self.tostr((0, 0, 1)) + ", "
|
||||
_cmd += offset
|
||||
_cmd += ")"
|
||||
FreeCADGui.doCommandGui(_cmd)
|
||||
self.display('Top')
|
||||
self.finish()
|
||||
|
||||
def onClickFront(self):
|
||||
|
||||
o = str(self.getOffset())
|
||||
FreeCADGui.doCommandGui(self.ac+"("+self.tostr(self.getCenterPoint(0,-1,0))+","+self.tostr((0,-1,0))+","+o+")")
|
||||
"""Execute when pressing the front button."""
|
||||
offset = str(self.getOffset())
|
||||
_cmd = self.ac
|
||||
_cmd += "("
|
||||
_cmd += self.tostr(self.getCenterPoint(0, -1, 0)) + ", "
|
||||
_cmd += self.tostr((0, -1, 0)) + ", "
|
||||
_cmd += offset
|
||||
_cmd += ")"
|
||||
FreeCADGui.doCommandGui(_cmd)
|
||||
self.display('Front')
|
||||
self.finish()
|
||||
|
||||
def onClickSide(self):
|
||||
|
||||
o = str(self.getOffset())
|
||||
FreeCADGui.doCommandGui(self.ac+"("+self.tostr(self.getCenterPoint(1,0,0))+","+self.tostr((1,0,0))+","+o+")")
|
||||
"""Execute when pressing the side button."""
|
||||
offset = str(self.getOffset())
|
||||
_cmd = self.ac
|
||||
_cmd += "("
|
||||
_cmd += self.tostr(self.getCenterPoint(1, 0, 0)) + ", "
|
||||
_cmd += self.tostr((1, 0, 0)) + ", "
|
||||
_cmd += offset
|
||||
_cmd += ")"
|
||||
FreeCADGui.doCommandGui(_cmd)
|
||||
self.display('Side')
|
||||
self.finish()
|
||||
|
||||
def onClickAlign(self):
|
||||
|
||||
"""Execute when pressing the align."""
|
||||
FreeCADGui.doCommandGui("FreeCAD.DraftWorkingPlane.setup(force=True)")
|
||||
d = self.view.getViewDirection().negative()
|
||||
self.display(d)
|
||||
self.finish()
|
||||
|
||||
def onClickAuto(self):
|
||||
|
||||
"""Execute when pressing the auto button."""
|
||||
FreeCADGui.doCommandGui("FreeCAD.DraftWorkingPlane.reset()")
|
||||
self.display('Auto')
|
||||
self.finish()
|
||||
|
||||
def onClickMove(self):
|
||||
|
||||
"""Execute when pressing the move button."""
|
||||
sel = FreeCADGui.Selection.getSelectionEx()
|
||||
if sel:
|
||||
verts = []
|
||||
import Part
|
||||
for s in sel:
|
||||
for so in s.SubObjects:
|
||||
if isinstance(so,Part.Vertex):
|
||||
if isinstance(so, Part.Vertex):
|
||||
verts.append(so)
|
||||
if len(verts) == 1:
|
||||
target = verts[0].Point
|
||||
@@ -358,13 +397,13 @@ class Draft_SelectPlane:
|
||||
c = FreeCADGui.ActiveDocument.ActiveView.getCameraNode()
|
||||
p = FreeCAD.Vector(c.position.getValue().getValue())
|
||||
d = FreeCADGui.ActiveDocument.ActiveView.getViewDirection()
|
||||
pp = FreeCAD.DraftWorkingPlane.projectPoint(p,d)
|
||||
pp = FreeCAD.DraftWorkingPlane.projectPoint(p, d)
|
||||
FreeCAD.DraftWorkingPlane.position = pp
|
||||
self.display(pp)
|
||||
self.finish()
|
||||
|
||||
def onClickCenter(self):
|
||||
|
||||
"""Execute when pressing the center button."""
|
||||
c = FreeCADGui.ActiveDocument.ActiveView.getCameraNode()
|
||||
r = FreeCAD.DraftWorkingPlane.getRotation().Rotation.Q
|
||||
c.orientation.setValue(r)
|
||||
@@ -377,7 +416,7 @@ class Draft_SelectPlane:
|
||||
self.finish()
|
||||
|
||||
def onClickPrevious(self):
|
||||
|
||||
"""Execute when pressing the previous button."""
|
||||
p = FreeCAD.DraftWorkingPlane
|
||||
if len(self.states) > 1:
|
||||
self.states.pop() # discard the last one
|
||||
@@ -389,32 +428,32 @@ class Draft_SelectPlane:
|
||||
FreeCADGui.Snapper.setGrid()
|
||||
self.finish()
|
||||
|
||||
def onSetGridSize(self,text):
|
||||
|
||||
def onSetGridSize(self, text):
|
||||
"""Execute when setting the grid size."""
|
||||
try:
|
||||
q = FreeCAD.Units.Quantity(text)
|
||||
except:
|
||||
except Exception:
|
||||
pass
|
||||
else:
|
||||
self.param.SetFloat("gridSpacing",q.Value)
|
||||
if hasattr(FreeCADGui,"Snapper"):
|
||||
self.param.SetFloat("gridSpacing", q.Value)
|
||||
if hasattr(FreeCADGui, "Snapper"):
|
||||
FreeCADGui.Snapper.setGrid()
|
||||
|
||||
def onSetMainline(self,i):
|
||||
|
||||
def onSetMainline(self, i):
|
||||
"""Execute when setting main line grid spacing."""
|
||||
if i > 1:
|
||||
self.param.SetInt("gridEvery",i)
|
||||
if hasattr(FreeCADGui,"Snapper"):
|
||||
self.param.SetInt("gridEvery", i)
|
||||
if hasattr(FreeCADGui, "Snapper"):
|
||||
FreeCADGui.Snapper.setGrid()
|
||||
|
||||
def onSetSnapRadius(self,i):
|
||||
|
||||
self.param.SetInt("snapRange",i)
|
||||
def onSetSnapRadius(self, i):
|
||||
"""Execute when setting the snap radius."""
|
||||
self.param.SetInt("snapRange", i)
|
||||
if hasattr(FreeCADGui, "Snapper"):
|
||||
FreeCADGui.Snapper.showradius()
|
||||
|
||||
def display(self,arg):
|
||||
"""Set the text of the working plane button."""
|
||||
def display(self, arg):
|
||||
"""Set the text of the working plane button in the toolbar."""
|
||||
o = self.getOffset()
|
||||
if o:
|
||||
if o > 0:
|
||||
@@ -423,63 +462,36 @@ class Draft_SelectPlane:
|
||||
suffix = ' -O'
|
||||
else:
|
||||
suffix = ''
|
||||
vdir = FreeCAD.DraftWorkingPlane.axis
|
||||
vdir = '('+str(vdir.x)[:4]+','+str(vdir.y)[:4]+','+str(vdir.z)[:4]+')'
|
||||
vdir = " "+translate("draft","Dir")+": "+vdir
|
||||
if type(arg).__name__ == 'str':
|
||||
self.wpButton.setText(arg+suffix)
|
||||
_vdir = FreeCAD.DraftWorkingPlane.axis
|
||||
vdir = '('
|
||||
vdir += str(_vdir.x)[:4] + ','
|
||||
vdir += str(_vdir.y)[:4] + ','
|
||||
vdir += str(_vdir.z)[:4]
|
||||
vdir += ')'
|
||||
|
||||
vdir = " " + translate("draft", "Dir") + ": " + vdir
|
||||
if type(arg).__name__ == 'str':
|
||||
self.wpButton.setText(arg + suffix)
|
||||
if o != 0:
|
||||
o = " "+translate("draft","Offset")+": "+str(o)
|
||||
o = " " + translate("draft", "Offset") + ": " + str(o)
|
||||
else:
|
||||
o = ""
|
||||
self.wpButton.setToolTip(translate("draft", "Current working plane")+": "+self.wpButton.text()+o+vdir)
|
||||
_tool = translate("draft", "Current working plane") + ": "
|
||||
_tool += self.wpButton.text() + o + vdir
|
||||
self.wpButton.setToolTip(_tool)
|
||||
elif type(arg).__name__ == 'Vector':
|
||||
plv = '('+str(arg.x)[:6]+','+str(arg.y)[:6]+','+str(arg.z)[:6]+')'
|
||||
self.wpButton.setText(translate("draft","Custom"))
|
||||
self.wpButton.setToolTip(translate("draft", "Current working plane")+": "+plv+vdir)
|
||||
plv = '('
|
||||
plv += str(arg.x)[:6] + ','
|
||||
plv += str(arg.y)[:6] + ','
|
||||
plv += str(arg.z)[:6]
|
||||
plv += ')'
|
||||
self.wpButton.setText(translate("draft", "Custom"))
|
||||
_tool = translate("draft", "Current working plane")
|
||||
_tool += ": " + plv + vdir
|
||||
self.wpButton.setToolTip(_tool)
|
||||
p = FreeCAD.DraftWorkingPlane
|
||||
self.states.append([p.u, p.v, p.axis, p.position])
|
||||
FreeCADGui.doCommandGui("FreeCADGui.Snapper.setGrid()")
|
||||
|
||||
|
||||
class SelectPlane_TaskPanel:
|
||||
"""The task panel definition of the Draft_SelectPlane command."""
|
||||
|
||||
def __init__(self):
|
||||
|
||||
import Draft_rc
|
||||
self.form = FreeCADGui.PySideUic.loadUi(":/ui/TaskSelectPlane.ui")
|
||||
|
||||
def getStandardButtons(self):
|
||||
|
||||
return 2097152 # int(QtGui.QDialogButtonBox.Close)
|
||||
|
||||
|
||||
class Draft_SetWorkingPlaneProxy():
|
||||
"""The Draft_SetWorkingPlaneProxy FreeCAD command definition"""
|
||||
|
||||
def GetResources(self):
|
||||
"""Set icon, menu and tooltip."""
|
||||
return {'Pixmap': 'Draft_SelectPlane',
|
||||
'MenuText': QT_TRANSLATE_NOOP("Draft_SetWorkingPlaneProxy", "Create Working Plane Proxy"),
|
||||
'ToolTip': QT_TRANSLATE_NOOP("Draft_SetWorkingPlaneProxy", "Creates a proxy object from the current working plane")}
|
||||
|
||||
def IsActive(self):
|
||||
"""Return True when this command should be available."""
|
||||
if FreeCADGui.ActiveDocument:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def Activated(self):
|
||||
"""Execute this when the command is called."""
|
||||
if hasattr(FreeCAD, "DraftWorkingPlane"):
|
||||
FreeCAD.ActiveDocument.openTransaction("Create WP proxy")
|
||||
FreeCADGui.addModule("Draft")
|
||||
FreeCADGui.doCommand("Draft.makeWorkingPlaneProxy(FreeCAD.DraftWorkingPlane.getPlacement())")
|
||||
FreeCAD.ActiveDocument.recompute()
|
||||
FreeCAD.ActiveDocument.commitTransaction()
|
||||
|
||||
|
||||
FreeCADGui.addCommand('Draft_SelectPlane', Draft_SelectPlane())
|
||||
FreeCADGui.addCommand('Draft_SetWorkingPlaneProxy', Draft_SetWorkingPlaneProxy())
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,9 +1,3 @@
|
||||
"""Provide the Draft_Snap commands used by the snapping mechanism in Draft."""
|
||||
## @package gui_snaps
|
||||
# \ingroup DRAFT
|
||||
# \brief Provide the Draft_Snap commands used by the snapping mechanism
|
||||
# in Draft.
|
||||
|
||||
# ***************************************************************************
|
||||
# * (c) 2009, 2010 Yorik van Havre <[email protected]> *
|
||||
# * (c) 2009, 2010 Ken Cline <[email protected]> *
|
||||
@@ -28,9 +22,16 @@
|
||||
# * USA *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
import FreeCADGui
|
||||
"""Provide the Draft_Snap commands used by the snapping mechanism in Draft."""
|
||||
## @package gui_snaps
|
||||
# \ingroup DRAFT
|
||||
# \brief Provide the Draft_Snap commands used by the snapping mechanism
|
||||
# in Draft.
|
||||
|
||||
from PySide.QtCore import QT_TRANSLATE_NOOP
|
||||
|
||||
import FreeCADGui as Gui
|
||||
|
||||
|
||||
class Draft_Snap_Lock:
|
||||
"""Command to activate or deactivate all snap commands."""
|
||||
@@ -47,12 +48,12 @@ class Draft_Snap_Lock:
|
||||
|
||||
def Activated(self):
|
||||
"""Execute this when the command is called."""
|
||||
if hasattr(FreeCADGui, "Snapper"):
|
||||
if hasattr(FreeCADGui.Snapper, "masterbutton"):
|
||||
FreeCADGui.Snapper.masterbutton.toggle()
|
||||
if hasattr(Gui, "Snapper"):
|
||||
if hasattr(Gui.Snapper, "masterbutton"):
|
||||
Gui.Snapper.masterbutton.toggle()
|
||||
|
||||
|
||||
FreeCADGui.addCommand('Draft_Snap_Lock', Draft_Snap_Lock())
|
||||
Gui.addCommand('Draft_Snap_Lock', Draft_Snap_Lock())
|
||||
|
||||
|
||||
class Draft_Snap_Midpoint:
|
||||
@@ -68,14 +69,14 @@ class Draft_Snap_Midpoint:
|
||||
|
||||
def Activated(self):
|
||||
"""Execute this when the command is called."""
|
||||
if hasattr(FreeCADGui, "Snapper"):
|
||||
if hasattr(FreeCADGui.Snapper, "toolbarButtons"):
|
||||
for b in FreeCADGui.Snapper.toolbarButtons:
|
||||
if hasattr(Gui, "Snapper"):
|
||||
if hasattr(Gui.Snapper, "toolbarButtons"):
|
||||
for b in Gui.Snapper.toolbarButtons:
|
||||
if b.objectName() == "SnapButtonmidpoint":
|
||||
b.toggle()
|
||||
|
||||
|
||||
FreeCADGui.addCommand('Draft_Snap_Midpoint', Draft_Snap_Midpoint())
|
||||
Gui.addCommand('Draft_Snap_Midpoint', Draft_Snap_Midpoint())
|
||||
|
||||
|
||||
class Draft_Snap_Perpendicular:
|
||||
@@ -93,14 +94,14 @@ class Draft_Snap_Perpendicular:
|
||||
|
||||
def Activated(self):
|
||||
"""Execute this when the command is called."""
|
||||
if hasattr(FreeCADGui, "Snapper"):
|
||||
if hasattr(FreeCADGui.Snapper, "toolbarButtons"):
|
||||
for b in FreeCADGui.Snapper.toolbarButtons:
|
||||
if hasattr(Gui, "Snapper"):
|
||||
if hasattr(Gui.Snapper, "toolbarButtons"):
|
||||
for b in Gui.Snapper.toolbarButtons:
|
||||
if b.objectName() == "SnapButtonperpendicular":
|
||||
b.toggle()
|
||||
|
||||
|
||||
FreeCADGui.addCommand('Draft_Snap_Perpendicular', Draft_Snap_Perpendicular())
|
||||
Gui.addCommand('Draft_Snap_Perpendicular', Draft_Snap_Perpendicular())
|
||||
|
||||
|
||||
class Draft_Snap_Grid:
|
||||
@@ -115,14 +116,14 @@ class Draft_Snap_Grid:
|
||||
|
||||
def Activated(self):
|
||||
"""Execute this when the command is called."""
|
||||
if hasattr(FreeCADGui, "Snapper"):
|
||||
if hasattr(FreeCADGui.Snapper, "toolbarButtons"):
|
||||
for b in FreeCADGui.Snapper.toolbarButtons:
|
||||
if hasattr(Gui, "Snapper"):
|
||||
if hasattr(Gui.Snapper, "toolbarButtons"):
|
||||
for b in Gui.Snapper.toolbarButtons:
|
||||
if b.objectName() == "SnapButtongrid":
|
||||
b.toggle()
|
||||
|
||||
|
||||
FreeCADGui.addCommand('Draft_Snap_Grid', Draft_Snap_Grid())
|
||||
Gui.addCommand('Draft_Snap_Grid', Draft_Snap_Grid())
|
||||
|
||||
|
||||
class Draft_Snap_Intersection:
|
||||
@@ -140,14 +141,14 @@ class Draft_Snap_Intersection:
|
||||
|
||||
def Activated(self):
|
||||
"""Execute this when the command is called."""
|
||||
if hasattr(FreeCADGui, "Snapper"):
|
||||
if hasattr(FreeCADGui.Snapper, "toolbarButtons"):
|
||||
for b in FreeCADGui.Snapper.toolbarButtons:
|
||||
if hasattr(Gui, "Snapper"):
|
||||
if hasattr(Gui.Snapper, "toolbarButtons"):
|
||||
for b in Gui.Snapper.toolbarButtons:
|
||||
if b.objectName() == "SnapButtonintersection":
|
||||
b.toggle()
|
||||
|
||||
|
||||
FreeCADGui.addCommand('Draft_Snap_Intersection', Draft_Snap_Intersection())
|
||||
Gui.addCommand('Draft_Snap_Intersection', Draft_Snap_Intersection())
|
||||
|
||||
|
||||
class Draft_Snap_Parallel:
|
||||
@@ -163,14 +164,14 @@ class Draft_Snap_Parallel:
|
||||
|
||||
def Activated(self):
|
||||
"""Execute this when the command is called."""
|
||||
if hasattr(FreeCADGui, "Snapper"):
|
||||
if hasattr(FreeCADGui.Snapper, "toolbarButtons"):
|
||||
for b in FreeCADGui.Snapper.toolbarButtons:
|
||||
if hasattr(Gui, "Snapper"):
|
||||
if hasattr(Gui.Snapper, "toolbarButtons"):
|
||||
for b in Gui.Snapper.toolbarButtons:
|
||||
if b.objectName() == "SnapButtonparallel":
|
||||
b.toggle()
|
||||
|
||||
|
||||
FreeCADGui.addCommand('Draft_Snap_Parallel', Draft_Snap_Parallel())
|
||||
Gui.addCommand('Draft_Snap_Parallel', Draft_Snap_Parallel())
|
||||
|
||||
|
||||
class Draft_Snap_Endpoint:
|
||||
@@ -186,14 +187,14 @@ class Draft_Snap_Endpoint:
|
||||
|
||||
def Activated(self):
|
||||
"""Execute this when the command is called."""
|
||||
if hasattr(FreeCADGui, "Snapper"):
|
||||
if hasattr(FreeCADGui.Snapper, "toolbarButtons"):
|
||||
for b in FreeCADGui.Snapper.toolbarButtons:
|
||||
if hasattr(Gui, "Snapper"):
|
||||
if hasattr(Gui.Snapper, "toolbarButtons"):
|
||||
for b in Gui.Snapper.toolbarButtons:
|
||||
if b.objectName() == "SnapButtonendpoint":
|
||||
b.toggle()
|
||||
|
||||
|
||||
FreeCADGui.addCommand('Draft_Snap_Endpoint', Draft_Snap_Endpoint())
|
||||
Gui.addCommand('Draft_Snap_Endpoint', Draft_Snap_Endpoint())
|
||||
|
||||
|
||||
class Draft_Snap_Angle:
|
||||
@@ -208,14 +209,14 @@ class Draft_Snap_Angle:
|
||||
|
||||
def Activated(self):
|
||||
"""Execute this when the command is called."""
|
||||
if hasattr(FreeCADGui, "Snapper"):
|
||||
if hasattr(FreeCADGui.Snapper, "toolbarButtons"):
|
||||
for b in FreeCADGui.Snapper.toolbarButtons:
|
||||
if hasattr(Gui, "Snapper"):
|
||||
if hasattr(Gui.Snapper, "toolbarButtons"):
|
||||
for b in Gui.Snapper.toolbarButtons:
|
||||
if b.objectName() == "SnapButtonangle":
|
||||
b.toggle()
|
||||
|
||||
|
||||
FreeCADGui.addCommand('Draft_Snap_Angle', Draft_Snap_Angle())
|
||||
Gui.addCommand('Draft_Snap_Angle', Draft_Snap_Angle())
|
||||
|
||||
|
||||
class Draft_Snap_Center:
|
||||
@@ -230,14 +231,14 @@ class Draft_Snap_Center:
|
||||
|
||||
def Activated(self):
|
||||
"""Execute this when the command is called."""
|
||||
if hasattr(FreeCADGui, "Snapper"):
|
||||
if hasattr(FreeCADGui.Snapper, "toolbarButtons"):
|
||||
for b in FreeCADGui.Snapper.toolbarButtons:
|
||||
if hasattr(Gui, "Snapper"):
|
||||
if hasattr(Gui.Snapper, "toolbarButtons"):
|
||||
for b in Gui.Snapper.toolbarButtons:
|
||||
if b.objectName() == "SnapButtoncenter":
|
||||
b.toggle()
|
||||
|
||||
|
||||
FreeCADGui.addCommand('Draft_Snap_Center', Draft_Snap_Center())
|
||||
Gui.addCommand('Draft_Snap_Center', Draft_Snap_Center())
|
||||
|
||||
|
||||
class Draft_Snap_Extension:
|
||||
@@ -253,14 +254,14 @@ class Draft_Snap_Extension:
|
||||
|
||||
def Activated(self):
|
||||
"""Execute this when the command is called."""
|
||||
if hasattr(FreeCADGui, "Snapper"):
|
||||
if hasattr(FreeCADGui.Snapper, "toolbarButtons"):
|
||||
for b in FreeCADGui.Snapper.toolbarButtons:
|
||||
if hasattr(Gui, "Snapper"):
|
||||
if hasattr(Gui.Snapper, "toolbarButtons"):
|
||||
for b in Gui.Snapper.toolbarButtons:
|
||||
if b.objectName() == "SnapButtonextension":
|
||||
b.toggle()
|
||||
|
||||
|
||||
FreeCADGui.addCommand('Draft_Snap_Extension', Draft_Snap_Extension())
|
||||
Gui.addCommand('Draft_Snap_Extension', Draft_Snap_Extension())
|
||||
|
||||
|
||||
class Draft_Snap_Near:
|
||||
@@ -275,14 +276,14 @@ class Draft_Snap_Near:
|
||||
|
||||
def Activated(self):
|
||||
"""Execute this when the command is called."""
|
||||
if hasattr(FreeCADGui, "Snapper"):
|
||||
if hasattr(FreeCADGui.Snapper, "toolbarButtons"):
|
||||
for b in FreeCADGui.Snapper.toolbarButtons:
|
||||
if hasattr(Gui, "Snapper"):
|
||||
if hasattr(Gui.Snapper, "toolbarButtons"):
|
||||
for b in Gui.Snapper.toolbarButtons:
|
||||
if b.objectName() == "SnapButtonpassive":
|
||||
b.toggle()
|
||||
|
||||
|
||||
FreeCADGui.addCommand('Draft_Snap_Near', Draft_Snap_Near())
|
||||
Gui.addCommand('Draft_Snap_Near', Draft_Snap_Near())
|
||||
|
||||
|
||||
class Draft_Snap_Ortho:
|
||||
@@ -297,14 +298,14 @@ class Draft_Snap_Ortho:
|
||||
|
||||
def Activated(self):
|
||||
"""Execute this when the command is called."""
|
||||
if hasattr(FreeCADGui, "Snapper"):
|
||||
if hasattr(FreeCADGui.Snapper, "toolbarButtons"):
|
||||
for b in FreeCADGui.Snapper.toolbarButtons:
|
||||
if hasattr(Gui, "Snapper"):
|
||||
if hasattr(Gui.Snapper, "toolbarButtons"):
|
||||
for b in Gui.Snapper.toolbarButtons:
|
||||
if b.objectName() == "SnapButtonortho":
|
||||
b.toggle()
|
||||
|
||||
|
||||
FreeCADGui.addCommand('Draft_Snap_Ortho', Draft_Snap_Ortho())
|
||||
Gui.addCommand('Draft_Snap_Ortho', Draft_Snap_Ortho())
|
||||
|
||||
|
||||
class Draft_Snap_Special:
|
||||
@@ -320,14 +321,14 @@ class Draft_Snap_Special:
|
||||
|
||||
def Activated(self):
|
||||
"""Execute this when the command is called."""
|
||||
if hasattr(FreeCADGui, "Snapper"):
|
||||
if hasattr(FreeCADGui.Snapper, "toolbarButtons"):
|
||||
for b in FreeCADGui.Snapper.toolbarButtons:
|
||||
if hasattr(Gui, "Snapper"):
|
||||
if hasattr(Gui.Snapper, "toolbarButtons"):
|
||||
for b in Gui.Snapper.toolbarButtons:
|
||||
if b.objectName() == "SnapButtonspecial":
|
||||
b.toggle()
|
||||
|
||||
|
||||
FreeCADGui.addCommand('Draft_Snap_Special', Draft_Snap_Special())
|
||||
Gui.addCommand('Draft_Snap_Special', Draft_Snap_Special())
|
||||
|
||||
|
||||
class Draft_Snap_Dimensions:
|
||||
@@ -343,14 +344,14 @@ class Draft_Snap_Dimensions:
|
||||
|
||||
def Activated(self):
|
||||
"""Execute this when the command is called."""
|
||||
if hasattr(FreeCADGui, "Snapper"):
|
||||
if hasattr(FreeCADGui.Snapper, "toolbarButtons"):
|
||||
for b in FreeCADGui.Snapper.toolbarButtons:
|
||||
if hasattr(Gui, "Snapper"):
|
||||
if hasattr(Gui.Snapper, "toolbarButtons"):
|
||||
for b in Gui.Snapper.toolbarButtons:
|
||||
if b.objectName() == "SnapButtonDimensions":
|
||||
b.toggle()
|
||||
|
||||
|
||||
FreeCADGui.addCommand('Draft_Snap_Dimensions', Draft_Snap_Dimensions())
|
||||
Gui.addCommand('Draft_Snap_Dimensions', Draft_Snap_Dimensions())
|
||||
|
||||
|
||||
class Draft_Snap_WorkingPlane:
|
||||
@@ -368,11 +369,11 @@ class Draft_Snap_WorkingPlane:
|
||||
|
||||
def Activated(self):
|
||||
"""Execute this when the command is called."""
|
||||
if hasattr(FreeCADGui, "Snapper"):
|
||||
if hasattr(FreeCADGui.Snapper, "toolbarButtons"):
|
||||
for b in FreeCADGui.Snapper.toolbarButtons:
|
||||
if hasattr(Gui, "Snapper"):
|
||||
if hasattr(Gui.Snapper, "toolbarButtons"):
|
||||
for b in Gui.Snapper.toolbarButtons:
|
||||
if b.objectName() == "SnapButtonWorkingPlane":
|
||||
b.toggle()
|
||||
|
||||
|
||||
FreeCADGui.addCommand('Draft_Snap_WorkingPlane', Draft_Snap_WorkingPlane())
|
||||
Gui.addCommand('Draft_Snap_WorkingPlane', Draft_Snap_WorkingPlane())
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,8 @@
|
||||
"""Functions and classes that define custom scripted objects.
|
||||
|
||||
These classes define a custom object which is based on one of the core
|
||||
objects defined in C++. The custom object inherits some basic properties,
|
||||
and new properties are added.
|
||||
|
||||
Most Draft objects are based on Part::Part2DObject.
|
||||
"""
|
||||
|
||||
@@ -1,8 +1,3 @@
|
||||
"""Provides the object code for Draft Arc_3Points."""
|
||||
## @package arc_3points
|
||||
# \ingroup DRAFT
|
||||
# \brief Provides the object code for Draft Arc_3Points.
|
||||
|
||||
# ***************************************************************************
|
||||
# * (c) 2020 Eliud Cabrera Castillo <[email protected]> *
|
||||
# * *
|
||||
@@ -25,14 +20,21 @@
|
||||
# * USA *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
"""Provides the object code for Draft Arc_3Points."""
|
||||
## @package arc_3points
|
||||
# \ingroup DRAFT
|
||||
# \brief Provides the object code for Draft Arc_3Points.
|
||||
|
||||
import math
|
||||
|
||||
import FreeCAD as App
|
||||
import Part
|
||||
import Draft
|
||||
from draftutils.messages import _msg, _err, _log
|
||||
import draftutils.utils as utils
|
||||
from draftutils.messages import _msg, _err
|
||||
from draftutils.translate import _tr
|
||||
if App.GuiUp:
|
||||
import draftutils.gui_utils as gui_utils
|
||||
|
||||
import draftutils.gui_utils as gui_utils
|
||||
|
||||
|
||||
def make_arc_3points(points, placement=None, face=False,
|
||||
@@ -109,40 +111,62 @@ def make_arc_3points(points, placement=None, face=False,
|
||||
Normally it returns a parametric Draft object (`Part::Part2DObject`).
|
||||
If `primitive` is `True`, it returns a basic `Part::Feature`.
|
||||
"""
|
||||
_log("make_arc_3points")
|
||||
_msg(16 * "-")
|
||||
_msg(_tr("Arc by 3 points"))
|
||||
_name = "make_arc_3points"
|
||||
utils.print_header(_name, "Arc by 3 points")
|
||||
|
||||
if not isinstance(points, (list, tuple)):
|
||||
_err(_tr("Wrong input: must be list or tuple of three points."))
|
||||
try:
|
||||
utils.type_check([(points, (list, tuple))], name=_name)
|
||||
except TypeError:
|
||||
_err(_tr("Points: ") + "{}".format(points))
|
||||
_err(_tr("Wrong input: "
|
||||
"must be list or tuple of three points exactly."))
|
||||
return None
|
||||
|
||||
if len(points) != 3:
|
||||
_err(_tr("Wrong input: must be three points."))
|
||||
_err(_tr("Points: ") + "{}".format(points))
|
||||
_err(_tr("Wrong input: "
|
||||
"must be list or tuple of three points exactly."))
|
||||
return None
|
||||
|
||||
if placement is not None:
|
||||
if not isinstance(placement, App.Placement):
|
||||
_err(_tr("Wrong input: incorrect placement"))
|
||||
try:
|
||||
utils.type_check([(placement, App.Placement)], name=_name)
|
||||
except TypeError:
|
||||
_err(_tr("Placement: ") + "{}".format(placement))
|
||||
_err(_tr("Wrong input: incorrect type of placement."))
|
||||
return None
|
||||
|
||||
p1, p2, p3 = points
|
||||
|
||||
_edge = Part.Arc(p1, p2, p3)
|
||||
_msg("p1: {}".format(p1))
|
||||
_msg("p2: {}".format(p2))
|
||||
_msg("p3: {}".format(p3))
|
||||
|
||||
try:
|
||||
utils.type_check([(p1, App.Vector),
|
||||
(p2, App.Vector),
|
||||
(p3, App.Vector)], name=_name)
|
||||
except TypeError:
|
||||
_err(_tr("Wrong input: incorrect type of points."))
|
||||
return None
|
||||
|
||||
try:
|
||||
_edge = Part.Arc(p1, p2, p3)
|
||||
except Part.OCCError as error:
|
||||
_err(_tr("Cannot generate shape: ") + "{}".format(error))
|
||||
return None
|
||||
|
||||
edge = _edge.toShape()
|
||||
radius = edge.Curve.Radius
|
||||
center = edge.Curve.Center
|
||||
|
||||
_msg("p1: {}".format(p1))
|
||||
_msg("p2: {}".format(p2))
|
||||
_msg("p3: {}".format(p3))
|
||||
_msg(_tr("Radius: ") + "{}".format(radius))
|
||||
_msg(_tr("Center: ") + "{}".format(center))
|
||||
|
||||
if primitive:
|
||||
_msg(_tr("Create primitive object"))
|
||||
obj = App.ActiveDocument.addObject("Part::Feature", "Arc")
|
||||
obj.Shape = edge
|
||||
_msg(_tr("Primitive object"))
|
||||
return obj
|
||||
|
||||
rot = App.Rotation(edge.Curve.XAxis,
|
||||
@@ -168,8 +192,8 @@ def make_arc_3points(points, placement=None, face=False,
|
||||
_msg(_tr("Face: True"))
|
||||
if support:
|
||||
_msg(_tr("Support: ") + "{}".format(support))
|
||||
obj.MapMode = map_mode
|
||||
_msg(_tr("Map mode: " + "{}".format(map_mode)))
|
||||
obj.MapMode = map_mode
|
||||
if placement:
|
||||
obj.AttachmentOffset.Base = placement.Base
|
||||
obj.AttachmentOffset.Rotation = original_placement.Rotation
|
||||
|
||||
@@ -1,9 +1,3 @@
|
||||
"""This module provides the object code for Draft CircularArray.
|
||||
"""
|
||||
## @package circulararray
|
||||
# \ingroup DRAFT
|
||||
# \brief This module provides the object code for Draft CircularArray.
|
||||
|
||||
# ***************************************************************************
|
||||
# * (c) 2019 Eliud Cabrera Castillo <[email protected]> *
|
||||
# * *
|
||||
@@ -26,20 +20,130 @@
|
||||
# * USA *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
"""Provides the object code for Draft CircularArray."""
|
||||
## @package circulararray
|
||||
# \ingroup DRAFT
|
||||
# \brief This module provides the object code for Draft CircularArray.
|
||||
|
||||
import FreeCAD as App
|
||||
import Draft
|
||||
import draftutils.utils as utils
|
||||
from draftutils.messages import _msg, _err
|
||||
from draftutils.translate import _tr
|
||||
|
||||
|
||||
def make_circular_array(obj,
|
||||
r_distance=100, tan_distance=100,
|
||||
axis=App.Vector(0, 0, 1), center=App.Vector(0, 0, 0),
|
||||
number=2, symmetry=1,
|
||||
use_link=False):
|
||||
axis=App.Vector(0, 0, 1), center=App.Vector(0, 0, 0),
|
||||
use_link=True):
|
||||
"""Create a circular array from the given object.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
obj: Part::Feature
|
||||
Any type of object that has a `Part::TopoShape`
|
||||
that can be duplicated.
|
||||
|
||||
r_distance: float, optional
|
||||
It defaults to `100`.
|
||||
Radial distance to the next ring of circular arrays.
|
||||
|
||||
tan_distance: float, optional
|
||||
It defaults to `100`.
|
||||
The tangential distance between two elements located
|
||||
in the same circular ring.
|
||||
The tangential distance together with the radial distance
|
||||
determine how many copies are created.
|
||||
|
||||
number: int, optional
|
||||
It defaults to 2.
|
||||
The number of layers or rings of repeated objects.
|
||||
The original object stays at the center, and is counted
|
||||
as a layer itself. So, if you want at least one layer of circular
|
||||
copies, this number must be at least 2.
|
||||
|
||||
symmetry: int, optional
|
||||
It defaults to 1.
|
||||
It indicates how many lines of symmetry the entire circular pattern
|
||||
has. That is, with 1, the array is symmetric only after a full
|
||||
360 degrees rotation.
|
||||
|
||||
When it is 2, the array is symmetric at 0 and 180 degrees.
|
||||
When it is 3, the array is symmetric at 0, 120, and 240 degrees.
|
||||
When it is 4, the array is symmetric at 0, 90, 180, and 270 degrees.
|
||||
Et cetera.
|
||||
|
||||
axis: Base::Vector3, optional
|
||||
It defaults to `App.Vector(0, 0, 1)` or the `+Z` axis.
|
||||
The unit vector indicating the axis of rotation.
|
||||
|
||||
center: Base::Vector3, optional
|
||||
It defaults to `App.Vector(0, 0, 0)` or the global origin.
|
||||
The point through which the `axis` passes to define
|
||||
the axis of rotation.
|
||||
|
||||
use_link: bool, optional
|
||||
It defaults to `True`.
|
||||
If it is `True` the produced copies are not `Part::TopoShape` copies,
|
||||
but rather `App::Link` objects.
|
||||
The Links repeat the shape of the original `obj` exactly,
|
||||
and therefore the resulting array is more memory efficient.
|
||||
|
||||
Also, when `use_link` is `True`, the `Fuse` property
|
||||
of the resulting array does not work; the array doesn't
|
||||
contain separate shapes, it only has the original shape repeated
|
||||
many times, so there is nothing to fuse together.
|
||||
|
||||
If `use_link` is `False` the original shape is copied many times.
|
||||
In this case the `Fuse` property is able to fuse
|
||||
all copies into a single object, if they touch each other.
|
||||
|
||||
Returns
|
||||
-------
|
||||
Part::FeaturePython
|
||||
A scripted object with `Proxy.Type='Array'`.
|
||||
Its `Shape` is a compound of the copies of the original object.
|
||||
"""
|
||||
obj = Draft.makeArray(obj,
|
||||
arg1=r_distance, arg2=tan_distance,
|
||||
arg3=axis, arg4=center, arg5=number, arg6=symmetry,
|
||||
use_link=use_link)
|
||||
return obj
|
||||
_name = "make_circular_array"
|
||||
utils.print_header(_name, _tr("Circular array"))
|
||||
|
||||
_msg("r_distance: {}".format(r_distance))
|
||||
_msg("tan_distance: {}".format(tan_distance))
|
||||
|
||||
try:
|
||||
utils.type_check([(r_distance, (int, float, App.Units.Quantity)),
|
||||
(tan_distance, (int, float, App.Units.Quantity))],
|
||||
name=_name)
|
||||
except TypeError:
|
||||
_err(_tr("Wrong input: must be a number or quantity."))
|
||||
return None
|
||||
|
||||
_msg("number: {}".format(number))
|
||||
_msg("symmetry: {}".format(symmetry))
|
||||
|
||||
try:
|
||||
utils.type_check([(number, int),
|
||||
(symmetry, int)], name=_name)
|
||||
except TypeError:
|
||||
_err(_tr("Wrong input: must be an integer number."))
|
||||
return None
|
||||
|
||||
_msg("axis: {}".format(axis))
|
||||
_msg("center: {}".format(center))
|
||||
|
||||
try:
|
||||
utils.type_check([(axis, App.Vector),
|
||||
(center, App.Vector)], name=_name)
|
||||
except TypeError:
|
||||
_err(_tr("Wrong input: must be a vector."))
|
||||
return None
|
||||
|
||||
_msg("use_link: {}".format(bool(use_link)))
|
||||
|
||||
new_obj = Draft.makeArray(obj,
|
||||
arg1=r_distance, arg2=tan_distance,
|
||||
arg3=axis, arg4=center,
|
||||
arg5=number, arg6=symmetry,
|
||||
use_link=use_link)
|
||||
return new_obj
|
||||
|
||||
@@ -1,8 +1,3 @@
|
||||
"""Provide the object code for Draft Array."""
|
||||
## @package orthoarray
|
||||
# \ingroup DRAFT
|
||||
# \brief Provide the object code for Draft Array.
|
||||
|
||||
# ***************************************************************************
|
||||
# * (c) 2020 Eliud Cabrera Castillo <[email protected]> *
|
||||
# * *
|
||||
@@ -25,9 +20,16 @@
|
||||
# * USA *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
"""Provide the object code for Draft Array."""
|
||||
## @package orthoarray
|
||||
# \ingroup DRAFT
|
||||
# \brief Provide the object code for Draft Array.
|
||||
|
||||
import FreeCAD as App
|
||||
import Draft
|
||||
import draftutils.utils as utils
|
||||
from draftutils.messages import _msg, _wrn, _err
|
||||
from draftutils.translate import _tr
|
||||
|
||||
|
||||
def make_ortho_array(obj,
|
||||
@@ -37,24 +39,376 @@ def make_ortho_array(obj,
|
||||
n_x=2,
|
||||
n_y=2,
|
||||
n_z=1,
|
||||
use_link=False):
|
||||
"""Create an orthogonal array from the given object."""
|
||||
obj = Draft.makeArray(obj,
|
||||
arg1=v_x, arg2=v_y, arg3=v_z,
|
||||
arg4=n_x, arg5=n_y, arg6=n_z,
|
||||
use_link=use_link)
|
||||
return obj
|
||||
use_link=True):
|
||||
"""Create an orthogonal array from the given object.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
obj: Part::Feature
|
||||
Any type of object that has a `Part::TopoShape`
|
||||
that can be duplicated.
|
||||
This means most 2D and 3D objects produced
|
||||
with any workbench.
|
||||
|
||||
v_x, v_y, v_z: Base::Vector3, optional
|
||||
The vector indicating the vector displacement between two elements
|
||||
in the specified orthogonal direction X, Y, Z.
|
||||
|
||||
By default:
|
||||
::
|
||||
v_x = App.Vector(10, 0, 0)
|
||||
v_y = App.Vector(0, 10, 0)
|
||||
v_z = App.Vector(0, 0, 10)
|
||||
|
||||
Given that this is a vectorial displacement
|
||||
the next object can appear displaced in one, two or three axes
|
||||
at the same time.
|
||||
|
||||
For example
|
||||
::
|
||||
v_x = App.Vector(10, 5, 0)
|
||||
|
||||
means that the next element in the X direction will be displaced
|
||||
10 mm in X, 5 mm in Y, and 0 mm in Z.
|
||||
|
||||
A traditional "rectangular" array is obtained when
|
||||
the displacement vector only has its corresponding component,
|
||||
like in the default case.
|
||||
|
||||
If these values are entered as single numbers instead
|
||||
of vectors, the single value is expanded into a vector
|
||||
of the corresponding direction, and the other components are assumed
|
||||
to be zero.
|
||||
|
||||
For example
|
||||
::
|
||||
v_x = 15
|
||||
v_y = 10
|
||||
v_z = 1
|
||||
becomes
|
||||
::
|
||||
v_x = App.Vector(15, 0, 0)
|
||||
v_y = App.Vector(0, 10, 0)
|
||||
v_z = App.Vector(0, 0, 1)
|
||||
|
||||
n_x, n_y, n_z: int, optional
|
||||
The number of copies in the specified orthogonal direction X, Y, Z.
|
||||
This number includes the original object, therefore, it must be
|
||||
at least 1.
|
||||
|
||||
The values of `n_x` and `n_y` default to 2,
|
||||
while `n_z` defaults to 1.
|
||||
This means the array by default is a planar array.
|
||||
|
||||
use_link: bool, optional
|
||||
It defaults to `True`.
|
||||
If it is `True` the produced copies are not `Part::TopoShape` copies,
|
||||
but rather `App::Link` objects.
|
||||
The Links repeat the shape of the original `obj` exactly,
|
||||
and therefore the resulting array is more memory efficient.
|
||||
|
||||
Also, when `use_link` is `True`, the `Fuse` property
|
||||
of the resulting array does not work; the array doesn't
|
||||
contain separate shapes, it only has the original shape repeated
|
||||
many times, so there is nothing to fuse together.
|
||||
|
||||
If `use_link` is `False` the original shape is copied many times.
|
||||
In this case the `Fuse` property is able to fuse
|
||||
all copies into a single object, if they touch each other.
|
||||
|
||||
Returns
|
||||
-------
|
||||
Part::FeaturePython
|
||||
A scripted object with `Proxy.Type='Array'`.
|
||||
Its `Shape` is a compound of the copies of the original object.
|
||||
|
||||
See Also
|
||||
--------
|
||||
make_ortho_array2d, make_rect_array, make_rect_array2d
|
||||
"""
|
||||
_name = "make_ortho_array"
|
||||
utils.print_header(_name, _tr("Orthogonal array"))
|
||||
|
||||
_msg("v_x: {}".format(v_x))
|
||||
_msg("v_y: {}".format(v_y))
|
||||
_msg("v_z: {}".format(v_z))
|
||||
|
||||
try:
|
||||
utils.type_check([(v_x, (int, float, App.Vector)),
|
||||
(v_y, (int, float, App.Vector)),
|
||||
(v_z, (int, float, App.Vector))],
|
||||
name=_name)
|
||||
except TypeError:
|
||||
_err(_tr("Wrong input: must be a number or vector."))
|
||||
return None
|
||||
|
||||
_text = "Input: single value expanded to vector."
|
||||
if not isinstance(v_x, App.Vector):
|
||||
v_x = App.Vector(v_x, 0, 0)
|
||||
_wrn(_tr(_text))
|
||||
if not isinstance(v_y, App.Vector):
|
||||
v_y = App.Vector(0, v_y, 0)
|
||||
_wrn(_tr(_text))
|
||||
if not isinstance(v_z, App.Vector):
|
||||
v_z = App.Vector(0, 0, v_z)
|
||||
_wrn(_tr(_text))
|
||||
|
||||
_msg("n_x: {}".format(n_x))
|
||||
_msg("n_y: {}".format(n_y))
|
||||
_msg("n_z: {}".format(n_z))
|
||||
|
||||
try:
|
||||
utils.type_check([(n_x, int),
|
||||
(n_y, int),
|
||||
(n_z, int)], name=_name)
|
||||
except TypeError:
|
||||
_err(_tr("Wrong input: must be an integer number."))
|
||||
return None
|
||||
|
||||
_text = ("Input: number of elements must be at least 1. "
|
||||
"It is set to 1.")
|
||||
if n_x < 1:
|
||||
_wrn(_tr(_text))
|
||||
n_x = 1
|
||||
if n_y < 1:
|
||||
_wrn(_tr(_text))
|
||||
n_y = 1
|
||||
if n_z < 1:
|
||||
_wrn(_tr(_text))
|
||||
n_z = 1
|
||||
|
||||
_msg("use_link: {}".format(bool(use_link)))
|
||||
|
||||
new_obj = Draft.makeArray(obj,
|
||||
arg1=v_x, arg2=v_y, arg3=v_z,
|
||||
arg4=n_x, arg5=n_y, arg6=n_z,
|
||||
use_link=use_link)
|
||||
return new_obj
|
||||
|
||||
|
||||
def make_ortho_array2(obj,
|
||||
v_x=App.Vector(10, 0, 0),
|
||||
v_y=App.Vector(0, 10, 0),
|
||||
def make_ortho_array2d(obj,
|
||||
v_x=App.Vector(10, 0, 0),
|
||||
v_y=App.Vector(0, 10, 0),
|
||||
n_x=2,
|
||||
n_y=2,
|
||||
use_link=True):
|
||||
"""Create a 2D orthogonal array from the given object.
|
||||
|
||||
This works the same as `make_ortho_array`.
|
||||
The Z component is ignored so it only considers vector displacements
|
||||
in X and Y directions.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
obj: Part::Feature
|
||||
Any type of object that has a `Part::TopoShape`
|
||||
that can be duplicated.
|
||||
This means most 2D and 3D objects produced
|
||||
with any workbench.
|
||||
|
||||
v_x, v_y: Base::Vector3, optional
|
||||
Vectorial displacement of elements
|
||||
in the corresponding X and Y directions.
|
||||
See `make_ortho_array`.
|
||||
|
||||
n_x, n_y: int, optional
|
||||
Number of elements
|
||||
in the corresponding X and Y directions.
|
||||
See `make_ortho_array`.
|
||||
|
||||
use_link: bool, optional
|
||||
If it is `True`, create `App::Link` array.
|
||||
See `make_ortho_array`.
|
||||
|
||||
Returns
|
||||
-------
|
||||
Part::FeaturePython
|
||||
A scripted object with `Proxy.Type='Array'`.
|
||||
Its `Shape` is a compound of the copies of the original object.
|
||||
|
||||
See Also
|
||||
--------
|
||||
make_ortho_array, make_rect_array, make_rect_array2d
|
||||
"""
|
||||
_name = "make_ortho_array2d"
|
||||
utils.print_header(_name, _tr("Orthogonal array 2D"))
|
||||
|
||||
_msg("v_x: {}".format(v_x))
|
||||
_msg("v_y: {}".format(v_y))
|
||||
|
||||
try:
|
||||
utils.type_check([(v_x, (int, float, App.Vector)),
|
||||
(v_y, (int, float, App.Vector))],
|
||||
name=_name)
|
||||
except TypeError:
|
||||
_err(_tr("Wrong input: must be a number or vector."))
|
||||
return None
|
||||
|
||||
_text = "Input: single value expanded to vector."
|
||||
if not isinstance(v_x, App.Vector):
|
||||
v_x = App.Vector(v_x, 0, 0)
|
||||
_wrn(_tr(_text))
|
||||
if not isinstance(v_y, App.Vector):
|
||||
v_y = App.Vector(0, v_y, 0)
|
||||
_wrn(_tr(_text))
|
||||
|
||||
_msg("n_x: {}".format(n_x))
|
||||
_msg("n_y: {}".format(n_y))
|
||||
|
||||
try:
|
||||
utils.type_check([(n_x, int),
|
||||
(n_y, int)], name=_name)
|
||||
except TypeError:
|
||||
_err(_tr("Wrong input: must be an integer number."))
|
||||
return None
|
||||
|
||||
_text = ("Input: number of elements must be at least 1. "
|
||||
"It is set to 1.")
|
||||
if n_x < 1:
|
||||
_wrn(_tr(_text))
|
||||
n_x = 1
|
||||
if n_y < 1:
|
||||
_wrn(_tr(_text))
|
||||
n_y = 1
|
||||
|
||||
_msg("use_link: {}".format(bool(use_link)))
|
||||
|
||||
new_obj = Draft.makeArray(obj,
|
||||
arg1=v_x, arg2=v_y,
|
||||
arg3=n_x, arg4=n_y,
|
||||
use_link=use_link)
|
||||
return new_obj
|
||||
|
||||
|
||||
def make_rect_array(obj,
|
||||
d_x=10,
|
||||
d_y=10,
|
||||
d_z=10,
|
||||
n_x=2,
|
||||
n_y=2,
|
||||
n_z=1,
|
||||
use_link=True):
|
||||
"""Create a rectangular array from the given object.
|
||||
|
||||
This function wraps around `make_ortho_array`
|
||||
to produce strictly rectangular arrays, in which
|
||||
the displacement vectors `v_x`, `v_y`, and `v_z`
|
||||
only have their respective components in X, Y, and Z.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
obj: Part::Feature
|
||||
Any type of object that has a `Part::TopoShape`
|
||||
that can be duplicated.
|
||||
This means most 2D and 3D objects produced
|
||||
with any workbench.
|
||||
|
||||
d_x, d_y, d_z: Base::Vector3, optional
|
||||
Displacement of elements in the corresponding X, Y, and Z directions.
|
||||
|
||||
n_x, n_y, n_z: int, optional
|
||||
Number of elements in the corresponding X, Y, and Z directions.
|
||||
|
||||
use_link: bool, optional
|
||||
If it is `True`, create `App::Link` array.
|
||||
See `make_ortho_array`.
|
||||
|
||||
Returns
|
||||
-------
|
||||
Part::FeaturePython
|
||||
A scripted object with `Proxy.Type='Array'`.
|
||||
Its `Shape` is a compound of the copies of the original object.
|
||||
|
||||
See Also
|
||||
--------
|
||||
make_ortho_array, make_ortho_array2d, make_rect_array2d
|
||||
"""
|
||||
_name = "make_rect_array"
|
||||
utils.print_header(_name, _tr("Rectangular array"))
|
||||
|
||||
_msg("d_x: {}".format(d_x))
|
||||
_msg("d_y: {}".format(d_y))
|
||||
_msg("d_z: {}".format(d_z))
|
||||
|
||||
try:
|
||||
utils.type_check([(d_x, (int, float)),
|
||||
(d_y, (int, float)),
|
||||
(d_z, (int, float))],
|
||||
name=_name)
|
||||
except TypeError:
|
||||
_err(_tr("Wrong input: must be a number."))
|
||||
return None
|
||||
|
||||
new_obj = make_ortho_array(obj,
|
||||
v_x=App.Vector(d_x, 0, 0),
|
||||
v_y=App.Vector(0, d_y, 0),
|
||||
v_z=App.Vector(0, 0, d_z),
|
||||
n_x=n_x,
|
||||
n_y=n_y,
|
||||
n_z=n_z,
|
||||
use_link=use_link)
|
||||
return new_obj
|
||||
|
||||
|
||||
def make_rect_array2d(obj,
|
||||
d_x=10,
|
||||
d_y=10,
|
||||
n_x=2,
|
||||
n_y=2,
|
||||
use_link=False):
|
||||
"""Create a 2D orthogonal array from the given object."""
|
||||
obj = Draft.makeArray(obj,
|
||||
arg1=v_x, arg2=v_y,
|
||||
arg3=n_x, arg4=n_y,
|
||||
use_link=use_link)
|
||||
return obj
|
||||
use_link=True):
|
||||
"""Create a 2D rectangular array from the given object.
|
||||
|
||||
This function wraps around `make_ortho_array2d`
|
||||
to produce strictly rectangular arrays, in which
|
||||
the displacement vectors `v_x` and `v_y`
|
||||
only have their respective components in X and Y.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
obj: Part::Feature
|
||||
Any type of object that has a `Part::TopoShape`
|
||||
that can be duplicated.
|
||||
This means most 2D and 3D objects produced
|
||||
with any workbench.
|
||||
|
||||
d_x, d_y: Base::Vector3, optional
|
||||
Displacement of elements in the corresponding X and Y directions.
|
||||
|
||||
n_x, n_y: int, optional
|
||||
Number of elements in the corresponding X and Y directions.
|
||||
|
||||
use_link: bool, optional
|
||||
If it is `True`, create `App::Link` array.
|
||||
See `make_ortho_array`.
|
||||
|
||||
Returns
|
||||
-------
|
||||
Part::FeaturePython
|
||||
A scripted object with `Proxy.Type='Array'`.
|
||||
Its `Shape` is a compound of the copies of the original object.
|
||||
|
||||
See Also
|
||||
--------
|
||||
make_ortho_array, make_ortho_array2d, make_rect_array
|
||||
"""
|
||||
_name = "make_rect_array2d"
|
||||
utils.print_header(_name, _tr("Rectangular array 2D"))
|
||||
|
||||
_msg("d_x: {}".format(d_x))
|
||||
_msg("d_y: {}".format(d_y))
|
||||
|
||||
try:
|
||||
utils.type_check([(d_x, (int, float)),
|
||||
(d_y, (int, float))],
|
||||
name=_name)
|
||||
except TypeError:
|
||||
_err(_tr("Wrong input: must be a number."))
|
||||
return None
|
||||
|
||||
new_obj = make_ortho_array2d(obj,
|
||||
v_x=App.Vector(d_x, 0, 0),
|
||||
v_y=App.Vector(0, d_y, 0),
|
||||
n_x=n_x,
|
||||
n_y=n_y,
|
||||
use_link=use_link)
|
||||
return new_obj
|
||||
|
||||
@@ -1,9 +1,3 @@
|
||||
"""This module provides the object code for Draft PolarArray.
|
||||
"""
|
||||
## @package polararray
|
||||
# \ingroup DRAFT
|
||||
# \brief This module provides the object code for Draft PolarArray.
|
||||
|
||||
# ***************************************************************************
|
||||
# * (c) 2019 Eliud Cabrera Castillo <[email protected]> *
|
||||
# * *
|
||||
@@ -26,17 +20,93 @@
|
||||
# * USA *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
"""Provide the object code for Draft PolarArray."""
|
||||
## @package polararray
|
||||
# \ingroup DRAFT
|
||||
# \brief This module provides the object code for Draft PolarArray.
|
||||
|
||||
import FreeCAD as App
|
||||
import Draft
|
||||
import draftutils.utils as utils
|
||||
from draftutils.messages import _msg, _err
|
||||
from draftutils.translate import _tr
|
||||
|
||||
|
||||
def make_polar_array(obj,
|
||||
center=App.Vector(0, 0, 0), angle=180, number=4,
|
||||
use_link=False):
|
||||
number=4, angle=360, center=App.Vector(0, 0, 0),
|
||||
use_link=True):
|
||||
"""Create a polar array from the given object.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
obj: Part::Feature
|
||||
Any type of object that has a `Part::TopoShape`
|
||||
that can be duplicated.
|
||||
This means most 2D and 3D objects produced
|
||||
with any workbench.
|
||||
|
||||
number: int, optional
|
||||
It defaults to 4.
|
||||
The number of copies produced in the circular pattern.
|
||||
|
||||
angle: float, optional
|
||||
It defaults to 360.
|
||||
The magnitude in degrees swept by the polar pattern.
|
||||
|
||||
center: Base::Vector3, optional
|
||||
It defaults to the origin `App.Vector(0, 0, 0)`.
|
||||
The vector indicating the center of rotation of the array.
|
||||
|
||||
use_link: bool, optional
|
||||
It defaults to `True`.
|
||||
If it is `True` the produced copies are not `Part::TopoShape` copies,
|
||||
but rather `App::Link` objects.
|
||||
The Links repeat the shape of the original `obj` exactly,
|
||||
and therefore the resulting array is more memory efficient.
|
||||
|
||||
Also, when `use_link` is `True`, the `Fuse` property
|
||||
of the resulting array does not work; the array doesn't
|
||||
contain separate shapes, it only has the original shape repeated
|
||||
many times, so there is nothing to fuse together.
|
||||
|
||||
If `use_link` is `False` the original shape is copied many times.
|
||||
In this case the `Fuse` property is able to fuse
|
||||
all copies into a single object, if they touch each other.
|
||||
|
||||
Returns
|
||||
-------
|
||||
Part::FeaturePython
|
||||
A scripted object with `Proxy.Type='Array'`.
|
||||
Its `Shape` is a compound of the copies of the original object.
|
||||
"""
|
||||
obj = Draft.makeArray(obj,
|
||||
arg1=center, arg2=angle, arg3=number,
|
||||
use_link=use_link)
|
||||
return obj
|
||||
_name = "make_polar_array"
|
||||
utils.print_header(_name, _tr("Polar array"))
|
||||
|
||||
_msg("Number: {}".format(number))
|
||||
_msg("Angle: {}".format(angle))
|
||||
_msg("Center: {}".format(center))
|
||||
|
||||
try:
|
||||
utils.type_check([(number, int)], name=_name)
|
||||
except TypeError:
|
||||
_err(_tr("Wrong input: must be an integer number."))
|
||||
return None
|
||||
|
||||
try:
|
||||
utils.type_check([(angle, (int, float))], name=_name)
|
||||
except TypeError:
|
||||
_err(_tr("Wrong input: must be a number."))
|
||||
return None
|
||||
|
||||
try:
|
||||
utils.type_check([(center, App.Vector)], name=_name)
|
||||
except TypeError:
|
||||
_err(_tr("Wrong input: must be a vector."))
|
||||
return None
|
||||
|
||||
_msg("use_link: {}".format(bool(use_link)))
|
||||
|
||||
new_obj = Draft.makeArray(obj,
|
||||
arg1=center, arg2=angle, arg3=number,
|
||||
use_link=use_link)
|
||||
return new_obj
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
"""Classes that define the task panels of GUI commands.
|
||||
|
||||
These classes load `.ui` files that will be used in the task panel
|
||||
of the graphical commands.
|
||||
The classes define the behavior and callbacks of the different widgets
|
||||
included in the `.ui` file.
|
||||
"""
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
# ***************************************************************************
|
||||
# * Copyright (c) 2019 Yorik van Havre <[email protected]> *
|
||||
# * *
|
||||
# * This file is part of the FreeCAD CAx development system. *
|
||||
# * *
|
||||
# * This program is free software; you can redistribute it and/or modify *
|
||||
# * it under the terms of the GNU Lesser General Public License (LGPL) *
|
||||
# * as published by the Free Software Foundation; either version 2 of *
|
||||
# * the License, or (at your option) any later version. *
|
||||
# * for detail see the LICENCE text file. *
|
||||
# * *
|
||||
# * FreeCAD is distributed in the hope that it will be useful, *
|
||||
# * but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
# * GNU Library General Public License for more details. *
|
||||
# * *
|
||||
# * You should have received a copy of the GNU Library General Public *
|
||||
# * License along with FreeCAD; if not, write to the Free Software *
|
||||
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
||||
# * USA *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
"""Provides the task panel for the Draft SelectPlane tool."""
|
||||
## @package task_selectplane
|
||||
# \ingroup DRAFT
|
||||
# \brief This module provides the task panel code for the SelectPlane tool.
|
||||
|
||||
import FreeCADGui as Gui
|
||||
|
||||
# As it is right now this code only loads the task panel .ui file.
|
||||
# All logic on how to use the widgets is located in the GuiCommand class
|
||||
# itself.
|
||||
# On the other hand, the newer tools introduced in v0.19 like OrthoArray,
|
||||
# PolarArray, and CircularArray include the logic and manipulation
|
||||
# of the widgets in this task panel class.
|
||||
# In addition, the task panel code launches the actual function
|
||||
# using the delayed mechanism defined by the `todo.ToDo` class.
|
||||
# Therefore, at some point this class should be refactored
|
||||
# to be more similar to OrthoArray and the new tools.
|
||||
|
||||
|
||||
class SelectPlaneTaskPanel:
|
||||
"""The task panel definition of the Draft_SelectPlane command."""
|
||||
|
||||
def __init__(self):
|
||||
self.form = Gui.PySideUic.loadUi(":/ui/TaskSelectPlane.ui")
|
||||
|
||||
def getStandardButtons(self):
|
||||
"""Execute to set the standard buttons."""
|
||||
return 2097152 # int(QtGui.QDialogButtonBox.Close)
|
||||
@@ -1 +1,7 @@
|
||||
#
|
||||
"""Classes and functions used to test the workbench.
|
||||
|
||||
These classes are called by the unit test launcher
|
||||
that is defined in `Init.py` and `InitGui.py`.
|
||||
|
||||
The unit tests are based on the standard `unittest` module.
|
||||
"""
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
"""Unit test for the Draft Workbench, GUI import tests."""
|
||||
|
||||
import unittest
|
||||
import FreeCAD as App
|
||||
import drafttests.auxiliary as aux
|
||||
|
||||
|
||||
@@ -39,39 +38,23 @@ class DraftGuiImport(unittest.TestCase):
|
||||
def test_import_gui_draftgui(self):
|
||||
"""Import Draft TaskView GUI tools."""
|
||||
module = "DraftGui"
|
||||
if not App.GuiUp:
|
||||
aux._no_gui(module)
|
||||
self.assertTrue(True)
|
||||
return
|
||||
imported = aux._import_test(module)
|
||||
self.assertTrue(imported, "Problem importing '{}'".format(module))
|
||||
|
||||
def test_import_gui_draft_snap(self):
|
||||
"""Import Draft snapping."""
|
||||
module = "draftguitools.gui_snapper"
|
||||
if not App.GuiUp:
|
||||
aux._no_gui(module)
|
||||
self.assertTrue(True)
|
||||
return
|
||||
imported = aux._import_test(module)
|
||||
self.assertTrue(imported, "Problem importing '{}'".format(module))
|
||||
|
||||
def test_import_gui_draft_tools(self):
|
||||
"""Import Draft graphical commands."""
|
||||
module = "DraftTools"
|
||||
if not App.GuiUp:
|
||||
aux._no_gui(module)
|
||||
self.assertTrue(True)
|
||||
return
|
||||
imported = aux._import_test(module)
|
||||
self.assertTrue(imported, "Problem importing '{}'".format(module))
|
||||
|
||||
def test_import_gui_draft_trackers(self):
|
||||
"""Import Draft tracker utilities."""
|
||||
module = "draftguitools.gui_trackers"
|
||||
if not App.GuiUp:
|
||||
aux._no_gui(module)
|
||||
self.assertTrue(True)
|
||||
return
|
||||
imported = aux._import_test(module)
|
||||
self.assertTrue(imported, "Problem importing '{}'".format(module))
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
"""Unit test for the Draft Workbench, tools import tests."""
|
||||
|
||||
import unittest
|
||||
import FreeCAD as App
|
||||
import drafttests.auxiliary as aux
|
||||
|
||||
|
||||
@@ -39,49 +38,29 @@ class DraftImportTools(unittest.TestCase):
|
||||
def test_import_gui_draftedit(self):
|
||||
"""Import Draft Edit."""
|
||||
module = "draftguitools.gui_edit"
|
||||
if not App.GuiUp:
|
||||
aux._no_gui(module)
|
||||
self.assertTrue(True)
|
||||
return
|
||||
imported = aux._import_test(module)
|
||||
self.assertTrue(imported, "Problem importing '{}'".format(module))
|
||||
|
||||
def test_import_gui_draftfillet(self):
|
||||
"""Import Draft Fillet."""
|
||||
module = "DraftFillet"
|
||||
if not App.GuiUp:
|
||||
aux._no_gui(module)
|
||||
self.assertTrue(True)
|
||||
return
|
||||
imported = aux._import_test(module)
|
||||
self.assertTrue(imported, "Problem importing '{}'".format(module))
|
||||
|
||||
def test_import_gui_draftlayer(self):
|
||||
"""Import Draft Layer."""
|
||||
module = "DraftLayer"
|
||||
if not App.GuiUp:
|
||||
aux._no_gui(module)
|
||||
self.assertTrue(True)
|
||||
return
|
||||
imported = aux._import_test(module)
|
||||
self.assertTrue(imported, "Problem importing '{}'".format(module))
|
||||
|
||||
def test_import_gui_draftplane(self):
|
||||
"""Import Draft SelectPlane."""
|
||||
module = "draftguitools.gui_selectplane"
|
||||
if not App.GuiUp:
|
||||
aux._no_gui(module)
|
||||
self.assertTrue(True)
|
||||
return
|
||||
imported = aux._import_test(module)
|
||||
self.assertTrue(imported, "Problem importing '{}'".format(module))
|
||||
|
||||
def test_import_gui_workingplane(self):
|
||||
"""Import Draft WorkingPlane."""
|
||||
module = "WorkingPlane"
|
||||
if not App.GuiUp:
|
||||
aux._no_gui(module)
|
||||
self.assertTrue(True)
|
||||
return
|
||||
imported = aux._import_test(module)
|
||||
self.assertTrue(imported, "Problem importing '{}'".format(module))
|
||||
|
||||
@@ -433,9 +433,9 @@ class DraftModification(unittest.TestCase):
|
||||
_msg(" Array")
|
||||
_msg(" radial_distance={0}, "
|
||||
"tangential_distance={1}".format(rad_distance, tan_distance))
|
||||
_msg(" number={0}, symmetry={1}".format(number, symmetry))
|
||||
_msg(" axis={}".format(axis))
|
||||
_msg(" center={}".format(center))
|
||||
_msg(" number={0}, symmetry={1}".format(number, symmetry))
|
||||
obj = Draft.makeArray(rect,
|
||||
rad_distance, tan_distance,
|
||||
axis, center,
|
||||
|
||||
@@ -58,14 +58,8 @@ class DraftPivy(unittest.TestCase):
|
||||
|
||||
def test_pivy_draw(self):
|
||||
"""Use Coin (pivy.coin) to draw a cube on the active view."""
|
||||
module = "pivy.coin"
|
||||
if not App.GuiUp:
|
||||
aux._no_gui(module)
|
||||
self.assertTrue(True)
|
||||
return
|
||||
|
||||
import pivy.coin
|
||||
cube = pivy.coin.SoCube()
|
||||
import pivy.coin as coin
|
||||
cube = coin.SoCube()
|
||||
_msg(" Draw cube")
|
||||
Gui.ActiveDocument.ActiveView.getSceneGraph().addChild(cube)
|
||||
_msg(" Adding cube to the active view scene")
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
"""Utility functions that do not require the graphical user interface.
|
||||
|
||||
These functions are used throughout the Draft Workbench.
|
||||
They can be called from any module, whether it uses the graphical
|
||||
user interface or not.
|
||||
"""
|
||||
|
||||
@@ -1,16 +1,8 @@
|
||||
"""This module provides GUI utility functions for the Draft Workbench.
|
||||
|
||||
This module should contain auxiliary functions which require
|
||||
the graphical user interface (GUI).
|
||||
"""
|
||||
## @package gui_utils
|
||||
# \ingroup DRAFT
|
||||
# \brief This module provides utility functions for the Draft Workbench
|
||||
|
||||
# ***************************************************************************
|
||||
# * (c) 2009, 2010 *
|
||||
# * Yorik van Havre <[email protected]>, Ken Cline <[email protected]> *
|
||||
# * (c) 2019 Eliud Cabrera Castillo <[email protected]> *
|
||||
# * (c) 2020 Carlo Pavan <[email protected]> *
|
||||
# * *
|
||||
# * This file is part of the FreeCAD CAx development system. *
|
||||
# * *
|
||||
@@ -31,24 +23,32 @@ the graphical user interface (GUI).
|
||||
# * USA *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
"""Provides GUI utility functions for the Draft Workbench.
|
||||
|
||||
This module contains auxiliary functions which can be used
|
||||
in other modules of the workbench, and which require
|
||||
the graphical user interface (GUI), as they access the view providers
|
||||
of the objects or the 3D view.
|
||||
"""
|
||||
## @package gui_utils
|
||||
# \ingroup DRAFT
|
||||
# \brief This module provides GUI utility functions for the Draft Workbench
|
||||
|
||||
import FreeCAD
|
||||
from .utils import _msg
|
||||
from .utils import _wrn
|
||||
# from .utils import _log
|
||||
from .utils import _tr
|
||||
from .utils import getParam
|
||||
from .utils import get_type
|
||||
import os
|
||||
import math
|
||||
import os
|
||||
import six
|
||||
|
||||
if FreeCAD.GuiUp:
|
||||
import FreeCADGui
|
||||
import FreeCAD as App
|
||||
from draftutils.messages import _msg, _wrn
|
||||
from draftutils.utils import getParam
|
||||
from draftutils.utils import get_type
|
||||
from draftutils.translate import _tr, translate
|
||||
|
||||
if App.GuiUp:
|
||||
import FreeCADGui as Gui
|
||||
from pivy import coin
|
||||
from PySide import QtGui
|
||||
# from PySide import QtSvg # for load_texture
|
||||
# from PySide import QtSvg # for load_texture
|
||||
|
||||
|
||||
def get_3d_view():
|
||||
@@ -62,13 +62,13 @@ def get_3d_view():
|
||||
|
||||
Return `None` if the graphical interface is not available.
|
||||
"""
|
||||
if FreeCAD.GuiUp:
|
||||
v = FreeCADGui.ActiveDocument.ActiveView
|
||||
if App.GuiUp:
|
||||
v = Gui.ActiveDocument.ActiveView
|
||||
if "View3DInventor" in str(type(v)):
|
||||
return v
|
||||
|
||||
# print("Debug: Draft: Warning, not working in active view")
|
||||
v = FreeCADGui.ActiveDocument.mdiViewsOfType("Gui::View3DInventor")
|
||||
v = Gui.ActiveDocument.mdiViewsOfType("Gui::View3DInventor")
|
||||
if v:
|
||||
return v[0]
|
||||
|
||||
@@ -80,10 +80,10 @@ get3DView = get_3d_view
|
||||
|
||||
|
||||
def autogroup(obj):
|
||||
"""Adds a given object to the defined Draft autogroup, if applicable.
|
||||
"""Add a given object to the defined Draft autogroup, if applicable.
|
||||
|
||||
This function only works if the graphical interface is available.
|
||||
It checks that the `FreeCAD.draftToolBar` class is available,
|
||||
It checks that the `App.draftToolBar` class is available,
|
||||
which contains the group to use to automatically store
|
||||
new created objects.
|
||||
|
||||
@@ -95,53 +95,58 @@ def autogroup(obj):
|
||||
|
||||
Parameters
|
||||
----------
|
||||
obj : App::DocumentObject
|
||||
obj: App::DocumentObject
|
||||
Any type of object that will be stored in the group.
|
||||
"""
|
||||
if FreeCAD.GuiUp:
|
||||
# look for active Arch container
|
||||
active_arch_obj = FreeCADGui.ActiveDocument.ActiveView.getActiveObject("Arch")
|
||||
if hasattr(FreeCADGui,"draftToolBar"):
|
||||
if (hasattr(FreeCADGui.draftToolBar,"autogroup")
|
||||
and not FreeCADGui.draftToolBar.isConstructionMode()
|
||||
):
|
||||
if FreeCADGui.draftToolBar.autogroup is not None:
|
||||
active_group = FreeCAD.ActiveDocument.getObject(FreeCADGui.draftToolBar.autogroup)
|
||||
if active_group:
|
||||
found = False
|
||||
for o in active_group.Group:
|
||||
if o.Name == obj.Name:
|
||||
found = True
|
||||
if not found:
|
||||
gr = active_group.Group
|
||||
gr.append(obj)
|
||||
active_group.Group = gr
|
||||
elif active_arch_obj:
|
||||
active_arch_obj.addObject(obj)
|
||||
elif FreeCADGui.ActiveDocument.ActiveView.getActiveObject("part", False) is not None:
|
||||
# add object to active part and change it's placement accordingly
|
||||
# so object does not jump to different position, works with App::Link
|
||||
# if not scaled. Modified accordingly to realthunder suggestions
|
||||
p, parent, sub = FreeCADGui.ActiveDocument.ActiveView.getActiveObject("part", False)
|
||||
matrix = parent.getSubObject(sub, retType=4)
|
||||
if matrix.hasScale() == 1:
|
||||
FreeCAD.Console.PrintMessage(translate("Draft",
|
||||
"Unable to insert new object into "
|
||||
"a scaled part")
|
||||
)
|
||||
return
|
||||
inverse_placement = FreeCAD.Placement(matrix.inverse())
|
||||
if get_type(obj) == 'Point':
|
||||
# point vector have a kind of placement, so should be
|
||||
# processed before generic object with placement
|
||||
point_vector = FreeCAD.Vector(obj.X, obj.Y, obj.Z)
|
||||
real_point = inverse_placement.multVec(point_vector)
|
||||
obj.X = real_point.x
|
||||
obj.Y = real_point.y
|
||||
obj.Z = real_point.z
|
||||
elif hasattr(obj,"Placement"):
|
||||
obj.Placement = FreeCAD.Placement(inverse_placement.multiply(obj.Placement))
|
||||
p.addObject(obj)
|
||||
if not App.GuiUp:
|
||||
return
|
||||
|
||||
doc = App.ActiveDocument
|
||||
view = Gui.ActiveDocument.ActiveView
|
||||
|
||||
# Look for active Arch container
|
||||
active_arch_obj = Gui.ActiveDocument.ActiveView.getActiveObject("Arch")
|
||||
if hasattr(Gui, "draftToolBar"):
|
||||
if (hasattr(Gui.draftToolBar, "autogroup")
|
||||
and not Gui.draftToolBar.isConstructionMode()):
|
||||
if Gui.draftToolBar.autogroup is not None:
|
||||
active_group = doc.getObject(Gui.draftToolBar.autogroup)
|
||||
if active_group:
|
||||
found = False
|
||||
for o in active_group.Group:
|
||||
if o.Name == obj.Name:
|
||||
found = True
|
||||
if not found:
|
||||
gr = active_group.Group
|
||||
gr.append(obj)
|
||||
active_group.Group = gr
|
||||
elif active_arch_obj:
|
||||
active_arch_obj.addObject(obj)
|
||||
elif view.getActiveObject("part", False) is not None:
|
||||
# Add object to active part and change its placement
|
||||
# accordingly so the object does not jump
|
||||
# to a different position, works with App::Link if not scaled.
|
||||
# Modified accordingly to realthunder suggestions
|
||||
p, parent, sub = view.getActiveObject("part", False)
|
||||
matrix = parent.getSubObject(sub, retType=4)
|
||||
if matrix.hasScale() == 1:
|
||||
_msg(translate("Draft",
|
||||
"Unable to insert new object into "
|
||||
"a scaled part"))
|
||||
return
|
||||
inverse_placement = App.Placement(matrix.inverse())
|
||||
if get_type(obj) == 'Point':
|
||||
# point vector have a kind of placement, so should be
|
||||
# processed before generic object with placement
|
||||
point_vector = App.Vector(obj.X, obj.Y, obj.Z)
|
||||
real_point = inverse_placement.multVec(point_vector)
|
||||
obj.X = real_point.x
|
||||
obj.Y = real_point.y
|
||||
obj.Z = real_point.z
|
||||
elif hasattr(obj, "Placement"):
|
||||
place = inverse_placement.multiply(obj.Placement)
|
||||
obj.Placement = App.Placement(place)
|
||||
p.addObject(obj)
|
||||
|
||||
|
||||
def dim_symbol(symbol=None, invert=False):
|
||||
@@ -149,7 +154,7 @@ def dim_symbol(symbol=None, invert=False):
|
||||
|
||||
Parameters
|
||||
----------
|
||||
symbol : int, optional
|
||||
symbol: int, optional
|
||||
It defaults to `None`, in which it gets the value from the parameter
|
||||
database, `get_param("dimsymbol", 0)`.
|
||||
|
||||
@@ -161,7 +166,7 @@ def dim_symbol(symbol=None, invert=False):
|
||||
* 4, `SoSeparator` with a `SoLineSet`, calling `dim_dash`
|
||||
* Otherwise, `SoSphere`
|
||||
|
||||
invert : bool, optional
|
||||
invert: bool, optional
|
||||
It defaults to `False`.
|
||||
If it is `True` and `symbol=2`, the cone will be rotated
|
||||
-90 degrees around the Z axis, otherwise the rotation is positive,
|
||||
@@ -181,7 +186,7 @@ def dim_symbol(symbol=None, invert=False):
|
||||
return coin.SoSphere()
|
||||
elif symbol == 1:
|
||||
marker = coin.SoMarkerSet()
|
||||
marker.markerIndex = FreeCADGui.getMarkerIndex("circle", 9)
|
||||
marker.markerIndex = Gui.getMarkerIndex("circle", 9)
|
||||
return marker
|
||||
elif symbol == 2:
|
||||
marker = coin.SoSeparator()
|
||||
@@ -224,10 +229,10 @@ def dim_dash(p1, p2):
|
||||
|
||||
Parameters
|
||||
----------
|
||||
p1 : tuple of three floats or Base::Vector3
|
||||
p1: tuple of three floats or Base::Vector3
|
||||
A point to define a line vertex.
|
||||
|
||||
p2 : tuple of three floats or Base::Vector3
|
||||
p2: tuple of three floats or Base::Vector3
|
||||
A point to define a line vertex.
|
||||
|
||||
Returns
|
||||
@@ -258,7 +263,7 @@ def remove_hidden(objectslist):
|
||||
|
||||
Parameters
|
||||
----------
|
||||
objectslist : list of App::DocumentObject
|
||||
objectslist: list of App::DocumentObject
|
||||
List of any type of object.
|
||||
|
||||
Returns
|
||||
@@ -291,19 +296,19 @@ def format_object(target, origin=None):
|
||||
|
||||
Parameters
|
||||
----------
|
||||
target : App::DocumentObject
|
||||
target: App::DocumentObject
|
||||
Any type of scripted object.
|
||||
|
||||
This object will adopt the applicable visual properties,
|
||||
`FontSize`, `TextColor`, `LineWidth`, `PointColor`, `LineColor`,
|
||||
and `ShapeColor`, defined in the Draft toolbar
|
||||
(`FreeCADGui.draftToolBar`) or will adopt
|
||||
(`Gui.draftToolBar`) or will adopt
|
||||
the properties from the `origin` object.
|
||||
|
||||
The `target` is also placed in the construction group
|
||||
if the construction mode in the Draft toolbar is active.
|
||||
|
||||
origin : App::DocumentObject, optional
|
||||
origin: App::DocumentObject, optional
|
||||
It defaults to `None`.
|
||||
If it exists, it will provide the visual properties to assign
|
||||
to `target`, with the exception of `BoundingBox`, `Proxy`,
|
||||
@@ -315,11 +320,11 @@ def format_object(target, origin=None):
|
||||
if not obrep:
|
||||
return
|
||||
ui = None
|
||||
if FreeCAD.GuiUp:
|
||||
if hasattr(FreeCADGui, "draftToolBar"):
|
||||
ui = FreeCADGui.draftToolBar
|
||||
if App.GuiUp:
|
||||
if hasattr(Gui, "draftToolBar"):
|
||||
ui = Gui.draftToolBar
|
||||
if ui:
|
||||
doc = FreeCAD.ActiveDocument
|
||||
doc = App.ActiveDocument
|
||||
if ui.isConstructionMode():
|
||||
col = fcol = ui.getDefaultColor("constr")
|
||||
gname = getParam("constructiongroupname", "Construction")
|
||||
@@ -374,18 +379,18 @@ def format_object(target, origin=None):
|
||||
formatObject = format_object
|
||||
|
||||
|
||||
def get_selection(gui=FreeCAD.GuiUp):
|
||||
def get_selection(gui=App.GuiUp):
|
||||
"""Return the current selected objects.
|
||||
|
||||
This function only works if the graphical interface is available
|
||||
as the selection module only works on the 3D view.
|
||||
|
||||
It wraps around `FreeCADGui.Selection.getSelection`
|
||||
It wraps around `Gui.Selection.getSelection`
|
||||
|
||||
Parameters
|
||||
----------
|
||||
gui : bool, optional
|
||||
It defaults to the value of `FreeCAD.GuiUp`, which is `True`
|
||||
gui: bool, optional
|
||||
It defaults to the value of `App.GuiUp`, which is `True`
|
||||
when the interface exists, and `False` otherwise.
|
||||
|
||||
This value can be set to `False` to simulate
|
||||
@@ -400,25 +405,25 @@ def get_selection(gui=FreeCAD.GuiUp):
|
||||
If the interface is not available, it returns `None`.
|
||||
"""
|
||||
if gui:
|
||||
return FreeCADGui.Selection.getSelection()
|
||||
return Gui.Selection.getSelection()
|
||||
return None
|
||||
|
||||
|
||||
getSelection = get_selection
|
||||
|
||||
|
||||
def get_selection_ex(gui=FreeCAD.GuiUp):
|
||||
def get_selection_ex(gui=App.GuiUp):
|
||||
"""Return the current selected objects together with their subelements.
|
||||
|
||||
This function only works if the graphical interface is available
|
||||
as the selection module only works on the 3D view.
|
||||
|
||||
It wraps around `FreeCADGui.Selection.getSelectionEx`
|
||||
It wraps around `Gui.Selection.getSelectionEx`
|
||||
|
||||
Parameters
|
||||
----------
|
||||
gui : bool, optional
|
||||
It defaults to the value of `FreeCAD.GuiUp`, which is `True`
|
||||
gui: bool, optional
|
||||
It defaults to the value of `App.GuiUp`, which is `True`
|
||||
when the interface exists, and `False` otherwise.
|
||||
|
||||
This value can be set to `False` to simulate
|
||||
@@ -448,14 +453,14 @@ def get_selection_ex(gui=FreeCAD.GuiUp):
|
||||
if `HasSubObjects` is `False`.
|
||||
"""
|
||||
if gui:
|
||||
return FreeCADGui.Selection.getSelectionEx()
|
||||
return Gui.Selection.getSelectionEx()
|
||||
return None
|
||||
|
||||
|
||||
getSelectionEx = get_selection_ex
|
||||
|
||||
|
||||
def select(objs=None, gui=FreeCAD.GuiUp):
|
||||
def select(objs=None, gui=App.GuiUp):
|
||||
"""Unselects everything and selects only the given list of objects.
|
||||
|
||||
This function only works if the graphical interface is available
|
||||
@@ -463,29 +468,29 @@ def select(objs=None, gui=FreeCAD.GuiUp):
|
||||
|
||||
Parameters
|
||||
----------
|
||||
objs : list of App::DocumentObject, optional
|
||||
objs: list of App::DocumentObject, optional
|
||||
It defaults to `None`.
|
||||
Any type of scripted object.
|
||||
It may be a list of objects or a single object.
|
||||
|
||||
gui : bool, optional
|
||||
It defaults to the value of `FreeCAD.GuiUp`, which is `True`
|
||||
gui: bool, optional
|
||||
It defaults to the value of `App.GuiUp`, which is `True`
|
||||
when the interface exists, and `False` otherwise.
|
||||
|
||||
This value can be set to `False` to simulate
|
||||
when the interface is not available.
|
||||
"""
|
||||
if gui:
|
||||
FreeCADGui.Selection.clearSelection()
|
||||
Gui.Selection.clearSelection()
|
||||
if objs:
|
||||
if not isinstance(objs, list):
|
||||
objs = [objs]
|
||||
for obj in objs:
|
||||
if obj:
|
||||
FreeCADGui.Selection.addSelection(obj)
|
||||
Gui.Selection.addSelection(obj)
|
||||
|
||||
|
||||
def load_texture(filename, size=None, gui=FreeCAD.GuiUp):
|
||||
def load_texture(filename, size=None, gui=App.GuiUp):
|
||||
"""Return a Coin.SoSFImage to use as a texture for a 2D plane.
|
||||
|
||||
This function only works if the graphical interface is available
|
||||
@@ -494,11 +499,11 @@ def load_texture(filename, size=None, gui=FreeCAD.GuiUp):
|
||||
|
||||
Parameters
|
||||
----------
|
||||
filename : str
|
||||
filename: str
|
||||
A path to a pixel image file (PNG) that can be used as a texture
|
||||
on the face of an object.
|
||||
|
||||
size : tuple of two int, or a single int, optional
|
||||
size: tuple of two int, or a single int, optional
|
||||
It defaults to `None`.
|
||||
If a tuple is given, the two values define the width and height
|
||||
in pixels to which the loaded image will be scaled.
|
||||
@@ -510,8 +515,8 @@ def load_texture(filename, size=None, gui=FreeCAD.GuiUp):
|
||||
CURRENTLY the input `size` parameter IS NOT USED.
|
||||
It always uses the `QImage` to determine this information.
|
||||
|
||||
gui : bool, optional
|
||||
It defaults to the value of `FreeCAD.GuiUp`, which is `True`
|
||||
gui: bool, optional
|
||||
It defaults to the value of `App.GuiUp`, which is `True`
|
||||
when the interface exists, and `False` otherwise.
|
||||
|
||||
This value can be set to `False` to simulate
|
||||
|
||||
@@ -1,14 +1,3 @@
|
||||
"""Provides lists of commands for the Draft Workbench.
|
||||
|
||||
This module returns lists of commands, so that the toolbars
|
||||
can be initialized by Draft, and by other workbenches.
|
||||
These commands should be defined in `DraftTools`, and in the individual
|
||||
modules in `draftguitools`.
|
||||
"""
|
||||
## @package init_tools
|
||||
# \ingroup DRAFT
|
||||
# \brief This module provides lists of commands for the Draft Workbench.
|
||||
|
||||
# ***************************************************************************
|
||||
# * (c) 2020 Eliud Cabrera Castillo <[email protected]> *
|
||||
# * *
|
||||
@@ -31,6 +20,16 @@ modules in `draftguitools`.
|
||||
# * USA *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
"""Provides lists of commands for the Draft Workbench.
|
||||
|
||||
This module returns lists of commands, so that the toolbars
|
||||
can be initialized by Draft, and by other workbenches.
|
||||
These commands should be defined in `DraftTools`, and in the individual
|
||||
modules in `draftguitools`.
|
||||
"""
|
||||
## @package init_tools
|
||||
# \ingroup DRAFT
|
||||
# \brief This module provides lists of commands for the Draft Workbench.
|
||||
|
||||
from PySide.QtCore import QT_TRANSLATE_NOOP
|
||||
|
||||
@@ -43,12 +42,13 @@ def get_draft_drawing_commands():
|
||||
"Draft_ArcTools",
|
||||
"Draft_Circle", "Draft_Ellipse", "Draft_Rectangle",
|
||||
"Draft_Polygon", "Draft_BSpline", "Draft_BezierTools",
|
||||
"Draft_Point", "Draft_Facebinder"]
|
||||
"Draft_Point", "Draft_Facebinder",
|
||||
"Draft_ShapeString"]
|
||||
|
||||
|
||||
def get_draft_annotation_commands():
|
||||
"""Return the annotation commands list."""
|
||||
return ["Draft_Text", "Draft_ShapeString", "Draft_Dimension",
|
||||
return ["Draft_Text", "Draft_Dimension",
|
||||
"Draft_Label"]
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ def get_draft_modification_commands():
|
||||
"""Return the modification commands list."""
|
||||
lst = ["Draft_Move", "Draft_Rotate",
|
||||
"Draft_Scale", "Draft_Mirror",
|
||||
"Draft_Offset", "Draft_Trimex",
|
||||
"Draft_Offset", "Draft_Trimex",
|
||||
"Draft_Stretch",
|
||||
"Separator",
|
||||
"Draft_Clone"]
|
||||
@@ -74,7 +74,8 @@ def get_draft_modification_commands():
|
||||
"Separator",
|
||||
"Draft_WireToBSpline", "Draft_Draft2Sketch",
|
||||
"Separator",
|
||||
"Draft_Shape2DView", "Draft_Drawing"]
|
||||
"Draft_Shape2DView", "Draft_Drawing",
|
||||
"Draft_WorkingPlaneProxy"]
|
||||
return lst
|
||||
|
||||
|
||||
@@ -97,7 +98,7 @@ def get_draft_utility_commands():
|
||||
return ["Draft_Layer", "Draft_Heal", "Draft_FlipDimension",
|
||||
"Draft_ToggleConstructionMode",
|
||||
"Draft_ToggleContinueMode", "Draft_Edit",
|
||||
"Draft_Slope", "Draft_SetWorkingPlaneProxy",
|
||||
"Draft_Slope", "Draft_WorkingPlaneProxy",
|
||||
"Draft_AddConstruction"]
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,3 @@
|
||||
"""Provide message utility functions for the Draft Workbench."""
|
||||
## @package messages
|
||||
# \ingroup DRAFT
|
||||
# \brief Provide message utility functions for the Draft Workbench.
|
||||
|
||||
# ***************************************************************************
|
||||
# * (c) 2020 Eliud Cabrera Castillo <[email protected]> *
|
||||
# * *
|
||||
@@ -25,6 +20,16 @@
|
||||
# * USA *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
"""Provide message utility functions for the Draft Workbench.
|
||||
|
||||
The Console module has long function names, so we define some shorthands
|
||||
that are suitable for use in every workbench. These shorthands also include
|
||||
a newline character at the end of the string, so it doesn't have to be
|
||||
added manually.
|
||||
"""
|
||||
## @package messages
|
||||
# \ingroup DRAFT
|
||||
# \brief Provide message utility functions for the Draft Workbench.
|
||||
|
||||
import FreeCAD as App
|
||||
|
||||
|
||||
@@ -1,12 +1,3 @@
|
||||
"""This module provides the ToDo class for the Draft Workbench.
|
||||
|
||||
This module provides the ToDo class to delay the commit of commands,
|
||||
which depends on QtCore.QTimer.
|
||||
"""
|
||||
## @package todo
|
||||
# \ingroup DRAFT
|
||||
# \brief This module provides the ToDo class for the Draft Workbench.
|
||||
|
||||
# ***************************************************************************
|
||||
# * (c) 2009, Yorik van Havre <[email protected]> *
|
||||
# * (c) 2019 Eliud Cabrera Castillo <[email protected]> *
|
||||
@@ -30,20 +21,33 @@ which depends on QtCore.QTimer.
|
||||
# * USA *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
"""Provides the ToDo class for the Draft Workbench.
|
||||
|
||||
The ToDo class is used to delay the commit of commands for later execution.
|
||||
This is necessary when a GUI command needs to manipulate the 3D view
|
||||
in such a way that a callback would crash Coin.
|
||||
The ToDo class essentially calls `QtCore.QTimer.singleShot`
|
||||
to execute the instructions stored in internal lists.
|
||||
"""
|
||||
## @package todo
|
||||
# \ingroup DRAFT
|
||||
# \brief This module provides the ToDo class for the Draft Workbench.
|
||||
|
||||
import sys
|
||||
import six
|
||||
import sys
|
||||
import traceback
|
||||
import FreeCAD
|
||||
import FreeCADGui
|
||||
from PySide import QtCore
|
||||
|
||||
import FreeCAD
|
||||
import FreeCADGui
|
||||
from draftutils.messages import _msg, _wrn, _log
|
||||
|
||||
__title__ = "FreeCAD Draft Workbench, Todo class"
|
||||
__author__ = "Yorik van Havre <[email protected]>"
|
||||
__url__ = ["http://www.freecadweb.org"]
|
||||
|
||||
_DEBUG = 0
|
||||
_DEBUG_inner = 0
|
||||
|
||||
|
||||
class ToDo:
|
||||
@@ -114,29 +118,31 @@ class ToDo:
|
||||
The lists are `itinerary`, `commitlist` and `afteritinerary`.
|
||||
"""
|
||||
if _DEBUG:
|
||||
print("Debug: doing delayed tasks.\n"
|
||||
"itinerary: {0}\n"
|
||||
"commitlist: {1}\n"
|
||||
"afteritinerary: {2}\n".format(todo.itinerary,
|
||||
todo.commitlist,
|
||||
todo.afteritinerary))
|
||||
_msg("Debug: doing delayed tasks.\n"
|
||||
"itinerary: {0}\n"
|
||||
"commitlist: {1}\n"
|
||||
"afteritinerary: {2}\n".format(todo.itinerary,
|
||||
todo.commitlist,
|
||||
todo.afteritinerary))
|
||||
try:
|
||||
for f, arg in todo.itinerary:
|
||||
try:
|
||||
# print("debug: executing", f)
|
||||
if _DEBUG_inner:
|
||||
_msg("Debug: executing.\n"
|
||||
"function: {}\n".format(f))
|
||||
if arg or (arg is False):
|
||||
f(arg)
|
||||
else:
|
||||
f()
|
||||
except Exception:
|
||||
FreeCAD.Console.PrintLog(traceback.format_exc())
|
||||
_log(traceback.format_exc())
|
||||
wrn = ("ToDo.doTasks, Unexpected error:\n"
|
||||
"{0}\n"
|
||||
"in {1}({2})".format(sys.exc_info()[0], f, arg))
|
||||
FreeCAD.Console.PrintWarning(wrn)
|
||||
_wrn(wrn)
|
||||
except ReferenceError:
|
||||
print("Debug: ToDo.doTasks: "
|
||||
"queue contains a deleted object, skipping")
|
||||
_wrn("Debug: ToDo.doTasks: "
|
||||
"queue contains a deleted object, skipping")
|
||||
todo.itinerary = []
|
||||
|
||||
if todo.commitlist:
|
||||
@@ -144,7 +150,9 @@ class ToDo:
|
||||
if six.PY2:
|
||||
if isinstance(name, six.text_type):
|
||||
name = name.encode("utf8")
|
||||
# print("debug: committing " + str(name))
|
||||
if _DEBUG_inner:
|
||||
_msg("Debug: committing.\n"
|
||||
"name: {}\n".format(name))
|
||||
try:
|
||||
name = str(name)
|
||||
FreeCAD.ActiveDocument.openTransaction(name)
|
||||
@@ -155,11 +163,11 @@ class ToDo:
|
||||
func()
|
||||
FreeCAD.ActiveDocument.commitTransaction()
|
||||
except Exception:
|
||||
FreeCAD.Console.PrintLog(traceback.format_exc())
|
||||
_log(traceback.format_exc())
|
||||
wrn = ("ToDo.doTasks, Unexpected error:\n"
|
||||
"{0}\n"
|
||||
"in {1}".format(sys.exec_info()[0], func))
|
||||
FreeCAD.Console.PrintWarning(wrn)
|
||||
"in {1}".format(sys.exc_info()[0], func))
|
||||
_wrn(wrn)
|
||||
# Restack Draft screen widgets after creation
|
||||
if hasattr(FreeCADGui, "Snapper"):
|
||||
FreeCADGui.Snapper.restack()
|
||||
@@ -167,17 +175,19 @@ class ToDo:
|
||||
|
||||
for f, arg in todo.afteritinerary:
|
||||
try:
|
||||
# print("debug: executing", f)
|
||||
if _DEBUG_inner:
|
||||
_msg("Debug: executing after.\n"
|
||||
"function: {}\n".format(f))
|
||||
if arg:
|
||||
f(arg)
|
||||
else:
|
||||
f()
|
||||
except Exception:
|
||||
FreeCAD.Console.PrintLog(traceback.format_exc())
|
||||
_log(traceback.format_exc())
|
||||
wrn = ("ToDo.doTasks, Unexpected error:\n"
|
||||
"{0}\n"
|
||||
"in {1}({2})".format(sys.exc_info()[0], f, arg))
|
||||
FreeCAD.Console.PrintWarning(wrn)
|
||||
_wrn(wrn)
|
||||
todo.afteritinerary = []
|
||||
|
||||
@staticmethod
|
||||
@@ -207,7 +217,9 @@ class ToDo:
|
||||
::
|
||||
f(arg)
|
||||
"""
|
||||
# print("debug: delaying", f)
|
||||
if _DEBUG:
|
||||
_msg("Debug: delaying.\n"
|
||||
"function: {}\n".format(f))
|
||||
if todo.itinerary == []:
|
||||
QtCore.QTimer.singleShot(0, todo.doTasks)
|
||||
todo.itinerary.append((f, arg))
|
||||
@@ -235,7 +247,9 @@ class ToDo:
|
||||
|
||||
See the attributes of the `ToDo` class for more information.
|
||||
"""
|
||||
# print("debug: delaying commit", cl)
|
||||
if _DEBUG:
|
||||
_msg("Debug: delaying commit.\n"
|
||||
"commitlist: {}\n".format(cl))
|
||||
QtCore.QTimer.singleShot(0, todo.doTasks)
|
||||
todo.commitlist = cl
|
||||
|
||||
@@ -255,7 +269,9 @@ class ToDo:
|
||||
Finally, it will build the tuple `(f, arg)`
|
||||
and append it to the `afteritinerary` list.
|
||||
"""
|
||||
# print("debug: delaying", f)
|
||||
if _DEBUG:
|
||||
_msg("Debug: delaying after.\n"
|
||||
"function: {}\n".format(f))
|
||||
if todo.afteritinerary == []:
|
||||
QtCore.QTimer.singleShot(0, todo.doTasks)
|
||||
todo.afteritinerary.append((f, arg))
|
||||
|
||||
@@ -1,13 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""This module provides utility functions for the Draft Workbench.
|
||||
|
||||
This module should contain auxiliary functions which don't require
|
||||
the graphical user interface (GUI).
|
||||
"""
|
||||
## @package utils
|
||||
# \ingroup DRAFT
|
||||
# \brief This module provides utility functions for the Draft Workbench
|
||||
|
||||
# ***************************************************************************
|
||||
# * (c) 2009, 2010 *
|
||||
# * Yorik van Havre <[email protected]>, Ken Cline <[email protected]> *
|
||||
@@ -32,52 +23,35 @@ the graphical user interface (GUI).
|
||||
# * USA *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
"""Provides utility functions for the Draft Workbench.
|
||||
|
||||
This module contains auxiliary functions which can be used
|
||||
in other modules of the workbench, and which don't require
|
||||
the graphical user interface (GUI).
|
||||
"""
|
||||
## @package utils
|
||||
# \ingroup DRAFT
|
||||
# \brief This module provides utility functions for the Draft Workbench
|
||||
|
||||
import os
|
||||
import FreeCAD
|
||||
from PySide import QtCore
|
||||
|
||||
import FreeCAD
|
||||
import Draft_rc
|
||||
from draftutils.messages import _msg, _log
|
||||
from draftutils.translate import _tr
|
||||
|
||||
App = FreeCAD
|
||||
|
||||
# The module is used to prevent complaints from code checkers (flake8)
|
||||
True if Draft_rc else False
|
||||
|
||||
|
||||
if App.GuiUp:
|
||||
# The right translate function needs to be imported here
|
||||
# from DraftGui import translate
|
||||
|
||||
# At the moment it is the same function as without GUI
|
||||
def translate(context, text):
|
||||
return text
|
||||
else:
|
||||
def translate(context, text):
|
||||
return text
|
||||
|
||||
|
||||
def _tr(text):
|
||||
"""Function to translate with the context set."""
|
||||
return translate("Draft", text)
|
||||
|
||||
|
||||
def _msg(text, end="\n"):
|
||||
App.Console.PrintMessage(text + end)
|
||||
|
||||
|
||||
def _wrn(text, end="\n"):
|
||||
App.Console.PrintWarning(text + end)
|
||||
|
||||
|
||||
def _log(text, end="\n"):
|
||||
App.Console.PrintLog(text + end)
|
||||
|
||||
|
||||
ARROW_TYPES = ["Dot", "Circle", "Arrow", "Tick", "Tick-2"]
|
||||
arrowtypes = ARROW_TYPES
|
||||
|
||||
|
||||
def string_encode_coin(ustr):
|
||||
"""Encode a unicode object to be used as a string in coin
|
||||
"""Encode a unicode object to be used as a string in coin.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
@@ -132,7 +106,7 @@ def type_check(args_and_types, name="?"):
|
||||
Defaults to `'?'`. The name of the check.
|
||||
|
||||
Raises
|
||||
-------
|
||||
------
|
||||
TypeError
|
||||
If the first element in the tuple is not an instance of the second
|
||||
element, it raises `Draft.name`.
|
||||
@@ -265,7 +239,7 @@ getParam = get_param
|
||||
|
||||
|
||||
def set_param(param, value):
|
||||
"""Set a Draft parameter with the given value
|
||||
"""Set a Draft parameter with the given value.
|
||||
|
||||
The parameter database is located in the tree
|
||||
::
|
||||
@@ -981,7 +955,7 @@ getMovableChildren = get_movable_children
|
||||
|
||||
|
||||
def utf8_decode(text):
|
||||
"""Decode the input string and return a unicode string.
|
||||
r"""Decode the input string and return a unicode string.
|
||||
|
||||
Python 2:
|
||||
::
|
||||
@@ -1017,14 +991,14 @@ def utf8_decode(text):
|
||||
|
||||
>>> "Aá".decode("utf-8")
|
||||
>>> b"Aá".decode("utf-8")
|
||||
u'A\\xe1'
|
||||
u'A\xe1'
|
||||
|
||||
In Python 2 the unicode string is prefixed with `u`,
|
||||
and unicode characters are replaced by their two-digit hexadecimal
|
||||
representation, or four digit unicode escape.
|
||||
|
||||
>>> "AáBẃCñ".decode("utf-8")
|
||||
u'A\\xe1B\\u1e83C\\xf1'
|
||||
u'A\xe1B\u1e83C\xf1'
|
||||
|
||||
In Python 2 it will always return a `unicode` object.
|
||||
|
||||
@@ -1045,3 +1019,29 @@ def utf8_decode(text):
|
||||
return text.decode("utf-8")
|
||||
except AttributeError:
|
||||
return text
|
||||
|
||||
|
||||
def print_header(name, description, debug=True):
|
||||
"""Print a line to the console when something is called, and log it.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
name: str
|
||||
The name of the function or class that is being called.
|
||||
This `name` will be logged in the log file, so if there are problems
|
||||
the log file can be investigated for clues.
|
||||
|
||||
description: str
|
||||
Arbitrary text that will be printed to the console
|
||||
when the function or class is called.
|
||||
|
||||
debug: bool, optional
|
||||
It defaults to `True`.
|
||||
If it is `False` the `description` will not be printed
|
||||
to the console.
|
||||
On the other hand the `name` will always be logged.
|
||||
"""
|
||||
_log(name)
|
||||
if debug:
|
||||
_msg(16 * "-")
|
||||
_msg(description)
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
"""Classes that define the viewproviders of custom scripted objects.
|
||||
|
||||
These classes define viewproviders for the custom objects
|
||||
defined in `draftobjects`.
|
||||
The viewproviders can be used only when the graphical interface
|
||||
is available; in console mode the viewproviders are not available.
|
||||
"""
|
||||
|
||||
+33
-35
@@ -1,23 +1,3 @@
|
||||
## @package importSVG
|
||||
# \ingroup DRAFT
|
||||
# \brief SVG file importer & exporter
|
||||
'''@package importSVG
|
||||
\ingroup DRAFT
|
||||
\brief SVG file importer & exporter
|
||||
|
||||
This module provides support for importing and exporting SVG files. It
|
||||
enables importing/exporting objects directly to/from the 3D document, but
|
||||
doesn't handle the SVG output from the Drawing and TechDraw modules.
|
||||
|
||||
Currently it only reads the following entities:
|
||||
* paths, lines, circular arcs, rects, circles, ellipses, polygons, polylines.
|
||||
|
||||
Currently unsupported:
|
||||
* use, image.
|
||||
'''
|
||||
# Check code with
|
||||
# flake8 --ignore=E226,E266,E401,W503
|
||||
|
||||
# ***************************************************************************
|
||||
# * Copyright (c) 2009 Yorik van Havre <[email protected]> *
|
||||
# * *
|
||||
@@ -38,12 +18,29 @@ Currently unsupported:
|
||||
# * USA *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
"""Provides support for importing and exporting SVG files.
|
||||
|
||||
It enables importing/exporting objects directly to/from the 3D document
|
||||
but doesn't handle the SVG output from the Drawing and TechDraw modules.
|
||||
|
||||
Currently it only reads the following entities:
|
||||
* paths, lines, circular arcs, rects, circles, ellipses, polygons, polylines.
|
||||
|
||||
Currently unsupported:
|
||||
* use, image.
|
||||
"""
|
||||
## @package importSVG
|
||||
# \ingroup DRAFT
|
||||
# \brief SVG file importer and exporter
|
||||
|
||||
# Check code with
|
||||
# flake8 --ignore=E226,E266,E401,W503
|
||||
|
||||
__title__ = "FreeCAD Draft Workbench - SVG importer/exporter"
|
||||
__author__ = "Yorik van Havre, Sebastian Hoogen"
|
||||
__url__ = "https://www.freecadweb.org"
|
||||
|
||||
# ToDo:
|
||||
# TODO:
|
||||
# ignoring CDATA
|
||||
# handle image element (external references and inline base64)
|
||||
# debug Problem with 'Sans' font from Inkscape
|
||||
@@ -51,27 +48,28 @@ __url__ = "https://www.freecadweb.org"
|
||||
# implement inheriting fill style from group
|
||||
# handle relative units
|
||||
|
||||
import xml.sax, FreeCAD, os, math, re, Draft, DraftVecUtils
|
||||
import math
|
||||
import os
|
||||
import re
|
||||
import xml.sax
|
||||
|
||||
import FreeCAD
|
||||
import Draft
|
||||
import DraftVecUtils
|
||||
from FreeCAD import Vector
|
||||
from FreeCAD import Console as FCC
|
||||
from draftutils.translate import translate
|
||||
|
||||
if FreeCAD.GuiUp:
|
||||
from DraftTools import translate
|
||||
from PySide import QtGui
|
||||
else:
|
||||
def translate(context, txt):
|
||||
return txt
|
||||
|
||||
try:
|
||||
import FreeCADGui
|
||||
except ImportError:
|
||||
gui = False
|
||||
else:
|
||||
gui = True
|
||||
|
||||
try:
|
||||
draftui = FreeCADGui.draftToolBar
|
||||
except AttributeError:
|
||||
try:
|
||||
draftui = FreeCADGui.draftToolBar
|
||||
except AttributeError:
|
||||
draftui = None
|
||||
else:
|
||||
gui = False
|
||||
draftui = None
|
||||
|
||||
# Save the native open function to avoid collisions
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
<string notr="true">mm</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>0.000000000000000</double>
|
||||
<double>0.000010000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>100000000.000000000000000</double>
|
||||
|
||||
@@ -94,7 +94,7 @@ public:
|
||||
* Computes appropriate bounding box for the given list of objects to be passed to setExtents ()
|
||||
* @param bboxAction a coin action for traverse the given objects views.
|
||||
* @param objs the list of objects to traverse, due to we traverse the scene graph, the geo children
|
||||
* will likely be traveresed too.
|
||||
* will likely be traversed too.
|
||||
*/
|
||||
static SbBox3f getRelevantBoundBox (
|
||||
SoGetBoundingBoxAction &bboxAction,
|
||||
|
||||
@@ -175,7 +175,6 @@ void Workbench::setupContextMenu(const char* recipient, Gui::MenuItem* item) con
|
||||
body = PartDesignGui::getBodyFor (feature, false, false, assertModern);
|
||||
// lote of assertion so feature should be marked as a tip
|
||||
if ( selection.size () == 1 && feature && (
|
||||
feature->isDerivedFrom ( PartDesign::Body::getClassTypeId () ) ||
|
||||
( feature->isDerivedFrom ( PartDesign::Feature::getClassTypeId () ) && body ) ||
|
||||
( feature->isDerivedFrom ( Part::Feature::getClassTypeId () ) && body &&
|
||||
body->BaseFeature.getValue() == feature )
|
||||
|
||||
@@ -119,7 +119,7 @@
|
||||
*
|
||||
* - \c default is the default value of this parameter. Right now, you must
|
||||
* supply a default value. Boost.PP has trouble dealing with empty values.
|
||||
* Remember that a sequence cannot be empty. Neight can tuple. Only array,
|
||||
* Remember that a sequence cannot be empty. Neither can tuple. Only array,
|
||||
* something like <tt>(0,())</tt> for an empty array. It is awkward to write,
|
||||
* and didn't add much functionality I want, hence the restriction of
|
||||
* non-empty defaults here.
|
||||
|
||||
@@ -45,41 +45,68 @@ if LOGLEVEL:
|
||||
else:
|
||||
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
|
||||
|
||||
|
||||
def updateInputField(obj, prop, widget, onBeforeChange=None):
|
||||
'''updateInputField(obj, prop, widget) ... update obj's property prop with the value of widget.
|
||||
The property's value is only assigned if the new value differs from the current value.
|
||||
This prevents onChanged notifications where the value didn't actually change.
|
||||
Gui::InputField and Gui::QuantitySpinBox widgets are supported - and the property can
|
||||
be of type Quantity or Float.
|
||||
If onBeforeChange is specified it is called before a new value is assigned to the property.
|
||||
Returns True if a new value was assigned, False otherwise (new value is the same as the current).
|
||||
'''
|
||||
The property's value is only assigned if the new value differs from the current value.
|
||||
This prevents onChanged notifications where the value didn't actually change.
|
||||
Gui::InputField and Gui::QuantitySpinBox widgets are supported - and the property can
|
||||
be of type Quantity or Float.
|
||||
If onBeforeChange is specified it is called before a new value is assigned to the property.
|
||||
Returns True if a new value was assigned, False otherwise (new value is the same as the current).
|
||||
'''
|
||||
value = FreeCAD.Units.Quantity(widget.text()).Value
|
||||
attr = PathUtil.getProperty(obj, prop)
|
||||
attrValue = attr.Value if hasattr(attr, 'Value') else attr
|
||||
|
||||
isDiff = False
|
||||
if not PathGeom.isRoughly(attrValue, value):
|
||||
isDiff = True
|
||||
else:
|
||||
if hasattr(obj, 'ExpressionEngine'):
|
||||
noExpr = True
|
||||
for (prp, expr) in obj.ExpressionEngine:
|
||||
if prp == prop:
|
||||
noExpr = False
|
||||
PathLog.debug('prop = "expression": {} = "{}"'.format(prp, expr))
|
||||
value = FreeCAD.Units.Quantity(obj.evalExpression(expr)).Value
|
||||
if not PathGeom.isRoughly(attrValue, value):
|
||||
isDiff = True
|
||||
break
|
||||
if noExpr:
|
||||
widget.setReadOnly(False)
|
||||
widget.setStyleSheet("color: black")
|
||||
else:
|
||||
widget.setReadOnly(True)
|
||||
widget.setStyleSheet("color: gray")
|
||||
widget.update()
|
||||
|
||||
if isDiff:
|
||||
PathLog.debug("updateInputField(%s, %s): %.2f -> %.2f" % (obj.Label, prop, attr, value))
|
||||
if onBeforeChange:
|
||||
onBeforeChange(obj)
|
||||
PathUtil.setProperty(obj, prop, value)
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
class QuantitySpinBox:
|
||||
'''Controller class to interface a Gui::QuantitySpinBox.
|
||||
The spin box gets bound to a given property and supports update in both directions.
|
||||
QuatitySpinBox(widget, obj, prop, onBeforeChange=None)
|
||||
widget ... expected to be reference to a Gui::QuantitySpinBox
|
||||
obj ... document object
|
||||
prop ... canonical name of the (sub-) property
|
||||
onBeforeChange ... an optional callback being executed before the value of the property is changed
|
||||
'''
|
||||
The spin box gets bound to a given property and supports update in both directions.
|
||||
QuatitySpinBox(widget, obj, prop, onBeforeChange=None)
|
||||
widget ... expected to be reference to a Gui::QuantitySpinBox
|
||||
obj ... document object
|
||||
prop ... canonical name of the (sub-) property
|
||||
onBeforeChange ... an optional callback being executed before the value of the property is changed
|
||||
'''
|
||||
|
||||
def __init__(self, widget, obj, prop, onBeforeChange=None):
|
||||
self.obj = obj
|
||||
self.widget = widget
|
||||
self.prop = prop
|
||||
self.onBeforeChange = onBeforeChange
|
||||
|
||||
attr = PathUtil.getProperty(self.obj, self.prop)
|
||||
if attr is not None:
|
||||
if hasattr(attr, 'Value'):
|
||||
@@ -95,7 +122,7 @@ The spin box gets bound to a given property and supports update in both directio
|
||||
if self.valid:
|
||||
return self.widget.property('expression')
|
||||
return ''
|
||||
|
||||
|
||||
def setMinimum(self, quantity):
|
||||
if self.valid:
|
||||
value = quantity.Value if hasattr(quantity, 'Value') else quantity
|
||||
@@ -103,8 +130,8 @@ The spin box gets bound to a given property and supports update in both directio
|
||||
|
||||
def updateSpinBox(self, quantity=None):
|
||||
'''updateSpinBox(quantity=None) ... update the display value of the spin box.
|
||||
If no value is provided the value of the bound property is used.
|
||||
quantity can be of type Quantity or Float.'''
|
||||
If no value is provided the value of the bound property is used.
|
||||
quantity can be of type Quantity or Float.'''
|
||||
if self.valid:
|
||||
if quantity is None:
|
||||
quantity = PathUtil.getProperty(self.obj, self.prop)
|
||||
@@ -116,4 +143,3 @@ quantity can be of type Quantity or Float.'''
|
||||
if self.valid:
|
||||
return updateInputField(self.obj, self.prop, self.widget, self.onBeforeChange)
|
||||
return None
|
||||
|
||||
|
||||
@@ -157,8 +157,6 @@ class ViewProvider(object):
|
||||
else:
|
||||
return ":/icons/Path-OpActive.svg"
|
||||
|
||||
#return self.OpIcon
|
||||
|
||||
def getTaskPanelOpPage(self, obj):
|
||||
'''getTaskPanelOpPage(obj) ... use the stored information to instantiate the receiver op's page controller.'''
|
||||
mod = importlib.import_module(self.OpPageModule)
|
||||
@@ -190,6 +188,7 @@ class ViewProvider(object):
|
||||
action.triggered.connect(self.setEdit)
|
||||
menu.addAction(action)
|
||||
|
||||
|
||||
class TaskPanelPage(object):
|
||||
'''Base class for all task panel pages.'''
|
||||
|
||||
@@ -377,7 +376,7 @@ class TaskPanelPage(object):
|
||||
combo.clear()
|
||||
combo.addItems(options)
|
||||
combo.blockSignals(False)
|
||||
|
||||
|
||||
if hasattr(obj, 'CoolantMode'):
|
||||
self.selectInComboBox(obj.CoolantMode, combo)
|
||||
|
||||
@@ -704,10 +703,13 @@ class TaskPanelDepthsPage(TaskPanelPage):
|
||||
|
||||
def haveStartDepth(self):
|
||||
return PathOp.FeatureDepths & self.features
|
||||
|
||||
def haveFinalDepth(self):
|
||||
return PathOp.FeatureDepths & self.features and not PathOp.FeatureNoFinalDepth & self.features
|
||||
|
||||
def haveFinishDepth(self):
|
||||
return PathOp.FeatureDepths & self.features and PathOp.FeatureFinishDepth & self.features
|
||||
|
||||
def haveStepDown(self):
|
||||
return PathOp.FeatureStepDown & self. features
|
||||
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
# include <QRegExp>
|
||||
# include <QShortcut>
|
||||
# include <QString>
|
||||
# include <QImage>
|
||||
# include <QPixmap>
|
||||
# include <boost/bind.hpp>
|
||||
#endif
|
||||
|
||||
@@ -663,34 +665,34 @@ void TaskSketcherElements::leaveEvent (QEvent * event)
|
||||
|
||||
void TaskSketcherElements::slotElementsChanged(void)
|
||||
{
|
||||
QIcon Sketcher_Element_Arc_Edge( Gui::BitmapFactory().iconFromTheme("Sketcher_Element_Arc_Edge") );
|
||||
QIcon Sketcher_Element_Arc_EndPoint( Gui::BitmapFactory().iconFromTheme("Sketcher_Element_Arc_EndPoint") );
|
||||
QIcon Sketcher_Element_Arc_MidPoint( Gui::BitmapFactory().iconFromTheme("Sketcher_Element_Arc_MidPoint") );
|
||||
QIcon Sketcher_Element_Arc_StartingPoint( Gui::BitmapFactory().iconFromTheme("Sketcher_Element_Arc_StartingPoint") );
|
||||
QIcon Sketcher_Element_Circle_Edge( Gui::BitmapFactory().iconFromTheme("Sketcher_Element_Circle_Edge") );
|
||||
QIcon Sketcher_Element_Circle_MidPoint( Gui::BitmapFactory().iconFromTheme("Sketcher_Element_Circle_MidPoint") );
|
||||
QIcon Sketcher_Element_Line_Edge( Gui::BitmapFactory().iconFromTheme("Sketcher_Element_Line_Edge") );
|
||||
QIcon Sketcher_Element_Line_EndPoint( Gui::BitmapFactory().iconFromTheme("Sketcher_Element_Line_EndPoint") );
|
||||
QIcon Sketcher_Element_Line_StartingPoint( Gui::BitmapFactory().iconFromTheme("Sketcher_Element_Line_StartingPoint") );
|
||||
QIcon Sketcher_Element_Point_StartingPoint( Gui::BitmapFactory().iconFromTheme("Sketcher_Element_Point_StartingPoint") );
|
||||
QIcon Sketcher_Element_Ellipse_Edge( Gui::BitmapFactory().iconFromTheme("Sketcher_Element_Ellipse_Edge_2") );
|
||||
QIcon Sketcher_Element_Ellipse_MidPoint( Gui::BitmapFactory().iconFromTheme("Sketcher_Element_Ellipse_CentrePoint") );
|
||||
QIcon Sketcher_Element_ArcOfEllipse_Edge( Gui::BitmapFactory().iconFromTheme("Sketcher_Element_Elliptical_Arc_Edge") );
|
||||
QIcon Sketcher_Element_ArcOfEllipse_MidPoint( Gui::BitmapFactory().iconFromTheme("Sketcher_Element_Elliptical_Arc_Centre_Point") );
|
||||
QIcon Sketcher_Element_ArcOfEllipse_StartingPoint( Gui::BitmapFactory().iconFromTheme("Sketcher_Element_Elliptical_Arc_Start_Point") );
|
||||
QIcon Sketcher_Element_ArcOfEllipse_EndPoint( Gui::BitmapFactory().iconFromTheme("Sketcher_Element_Elliptical_Arc_End_Point") );
|
||||
QIcon Sketcher_Element_ArcOfHyperbola_Edge( Gui::BitmapFactory().iconFromTheme("Sketcher_Element_Hyperbolic_Arc_Edge") );
|
||||
QIcon Sketcher_Element_ArcOfHyperbola_MidPoint( Gui::BitmapFactory().iconFromTheme("Sketcher_Element_Hyperbolic_Arc_Centre_Point") );
|
||||
QIcon Sketcher_Element_ArcOfHyperbola_StartingPoint( Gui::BitmapFactory().iconFromTheme("Sketcher_Element_Hyperbolic_Arc_Start_Point") );
|
||||
QIcon Sketcher_Element_ArcOfHyperbola_EndPoint( Gui::BitmapFactory().iconFromTheme("Sketcher_Element_Hyperbolic_Arc_End_Point") );
|
||||
QIcon Sketcher_Element_ArcOfParabola_Edge( Gui::BitmapFactory().iconFromTheme("Sketcher_Element_Parabolic_Arc_Edge") );
|
||||
QIcon Sketcher_Element_ArcOfParabola_MidPoint( Gui::BitmapFactory().iconFromTheme("Sketcher_Element_Parabolic_Arc_Centre_Point") );
|
||||
QIcon Sketcher_Element_ArcOfParabola_StartingPoint( Gui::BitmapFactory().iconFromTheme("Sketcher_Element_Parabolic_Arc_Start_Point") );
|
||||
QIcon Sketcher_Element_ArcOfParabola_EndPoint( Gui::BitmapFactory().iconFromTheme("Sketcher_Element_Parabolic_Arc_End_Point") );
|
||||
QIcon Sketcher_Element_BSpline_Edge( Gui::BitmapFactory().iconFromTheme("Sketcher_Element_BSpline_Edge") );
|
||||
QIcon Sketcher_Element_BSpline_StartingPoint( Gui::BitmapFactory().iconFromTheme("Sketcher_Element_BSpline_StartPoint") );
|
||||
QIcon Sketcher_Element_BSpline_EndPoint( Gui::BitmapFactory().iconFromTheme("Sketcher_Element_BSpline_EndPoint") );
|
||||
QIcon none( Gui::BitmapFactory().iconFromTheme("Sketcher_Element_SelectionTypeInvalid") );
|
||||
MultIcon Sketcher_Element_Arc_Edge("Sketcher_Element_Arc_Edge");
|
||||
MultIcon Sketcher_Element_Arc_EndPoint("Sketcher_Element_Arc_EndPoint");
|
||||
MultIcon Sketcher_Element_Arc_MidPoint("Sketcher_Element_Arc_MidPoint");
|
||||
MultIcon Sketcher_Element_Arc_StartingPoint("Sketcher_Element_Arc_StartingPoint");
|
||||
MultIcon Sketcher_Element_Circle_Edge("Sketcher_Element_Circle_Edge");
|
||||
MultIcon Sketcher_Element_Circle_MidPoint("Sketcher_Element_Circle_MidPoint");
|
||||
MultIcon Sketcher_Element_Line_Edge("Sketcher_Element_Line_Edge");
|
||||
MultIcon Sketcher_Element_Line_EndPoint("Sketcher_Element_Line_EndPoint");
|
||||
MultIcon Sketcher_Element_Line_StartingPoint("Sketcher_Element_Line_StartingPoint");
|
||||
MultIcon Sketcher_Element_Point_StartingPoint("Sketcher_Element_Point_StartingPoint");
|
||||
MultIcon Sketcher_Element_Ellipse_Edge("Sketcher_Element_Ellipse_Edge_2");
|
||||
MultIcon Sketcher_Element_Ellipse_MidPoint("Sketcher_Element_Ellipse_CentrePoint");
|
||||
MultIcon Sketcher_Element_ArcOfEllipse_Edge("Sketcher_Element_Elliptical_Arc_Edge");
|
||||
MultIcon Sketcher_Element_ArcOfEllipse_MidPoint("Sketcher_Element_Elliptical_Arc_Centre_Point");
|
||||
MultIcon Sketcher_Element_ArcOfEllipse_StartingPoint("Sketcher_Element_Elliptical_Arc_Start_Point");
|
||||
MultIcon Sketcher_Element_ArcOfEllipse_EndPoint("Sketcher_Element_Elliptical_Arc_End_Point");
|
||||
MultIcon Sketcher_Element_ArcOfHyperbola_Edge("Sketcher_Element_Hyperbolic_Arc_Edge");
|
||||
MultIcon Sketcher_Element_ArcOfHyperbola_MidPoint("Sketcher_Element_Hyperbolic_Arc_Centre_Point");
|
||||
MultIcon Sketcher_Element_ArcOfHyperbola_StartingPoint("Sketcher_Element_Hyperbolic_Arc_Start_Point");
|
||||
MultIcon Sketcher_Element_ArcOfHyperbola_EndPoint("Sketcher_Element_Hyperbolic_Arc_End_Point");
|
||||
MultIcon Sketcher_Element_ArcOfParabola_Edge("Sketcher_Element_Parabolic_Arc_Edge");
|
||||
MultIcon Sketcher_Element_ArcOfParabola_MidPoint("Sketcher_Element_Parabolic_Arc_Centre_Point");
|
||||
MultIcon Sketcher_Element_ArcOfParabola_StartingPoint("Sketcher_Element_Parabolic_Arc_Start_Point");
|
||||
MultIcon Sketcher_Element_ArcOfParabola_EndPoint("Sketcher_Element_Parabolic_Arc_End_Point");
|
||||
MultIcon Sketcher_Element_BSpline_Edge("Sketcher_Element_BSpline_Edge");
|
||||
MultIcon Sketcher_Element_BSpline_StartingPoint("Sketcher_Element_BSpline_StartPoint");
|
||||
MultIcon Sketcher_Element_BSpline_EndPoint("Sketcher_Element_BSpline_EndPoint");
|
||||
MultIcon none("Sketcher_Element_SelectionTypeInvalid");
|
||||
|
||||
assert(sketchView);
|
||||
// Build up ListView with the elements
|
||||
@@ -707,34 +709,34 @@ void TaskSketcherElements::slotElementsChanged(void)
|
||||
bool construction = (*it)->Construction;
|
||||
|
||||
ui->listWidgetElements->addItem(new ElementItem(
|
||||
(type == Part::GeomPoint::getClassTypeId() && element==1) ? Sketcher_Element_Point_StartingPoint :
|
||||
(type == Part::GeomLineSegment::getClassTypeId() && element==0) ? Sketcher_Element_Line_Edge :
|
||||
(type == Part::GeomLineSegment::getClassTypeId() && element==1) ? Sketcher_Element_Line_StartingPoint :
|
||||
(type == Part::GeomLineSegment::getClassTypeId() && element==2) ? Sketcher_Element_Line_EndPoint :
|
||||
(type == Part::GeomArcOfCircle::getClassTypeId() && element==0) ? Sketcher_Element_Arc_Edge :
|
||||
(type == Part::GeomArcOfCircle::getClassTypeId() && element==1) ? Sketcher_Element_Arc_StartingPoint :
|
||||
(type == Part::GeomArcOfCircle::getClassTypeId() && element==2) ? Sketcher_Element_Arc_EndPoint :
|
||||
(type == Part::GeomArcOfCircle::getClassTypeId() && element==3) ? Sketcher_Element_Arc_MidPoint :
|
||||
(type == Part::GeomCircle::getClassTypeId() && element==0) ? Sketcher_Element_Circle_Edge :
|
||||
(type == Part::GeomCircle::getClassTypeId() && element==3) ? Sketcher_Element_Circle_MidPoint :
|
||||
(type == Part::GeomEllipse::getClassTypeId() && element==0) ? Sketcher_Element_Ellipse_Edge :
|
||||
(type == Part::GeomEllipse::getClassTypeId() && element==3) ? Sketcher_Element_Ellipse_MidPoint :
|
||||
(type == Part::GeomArcOfEllipse::getClassTypeId() && element==0) ? Sketcher_Element_ArcOfEllipse_Edge :
|
||||
(type == Part::GeomArcOfEllipse::getClassTypeId() && element==1) ? Sketcher_Element_ArcOfEllipse_StartingPoint :
|
||||
(type == Part::GeomArcOfEllipse::getClassTypeId() && element==2) ? Sketcher_Element_ArcOfEllipse_EndPoint :
|
||||
(type == Part::GeomArcOfEllipse::getClassTypeId() && element==3) ? Sketcher_Element_ArcOfEllipse_MidPoint :
|
||||
(type == Part::GeomArcOfHyperbola::getClassTypeId() && element==0) ? Sketcher_Element_ArcOfHyperbola_Edge :
|
||||
(type == Part::GeomArcOfHyperbola::getClassTypeId() && element==1) ? Sketcher_Element_ArcOfHyperbola_StartingPoint :
|
||||
(type == Part::GeomArcOfHyperbola::getClassTypeId() && element==2) ? Sketcher_Element_ArcOfHyperbola_EndPoint :
|
||||
(type == Part::GeomArcOfHyperbola::getClassTypeId() && element==3) ? Sketcher_Element_ArcOfHyperbola_MidPoint :
|
||||
(type == Part::GeomArcOfParabola::getClassTypeId() && element==0) ? Sketcher_Element_ArcOfParabola_Edge :
|
||||
(type == Part::GeomArcOfParabola::getClassTypeId() && element==1) ? Sketcher_Element_ArcOfParabola_StartingPoint :
|
||||
(type == Part::GeomArcOfParabola::getClassTypeId() && element==2) ? Sketcher_Element_ArcOfParabola_EndPoint :
|
||||
(type == Part::GeomArcOfParabola::getClassTypeId() && element==3) ? Sketcher_Element_ArcOfParabola_MidPoint :
|
||||
(type == Part::GeomBSplineCurve::getClassTypeId() && element==0) ? Sketcher_Element_BSpline_Edge :
|
||||
(type == Part::GeomBSplineCurve::getClassTypeId() && element==1) ? Sketcher_Element_BSpline_StartingPoint :
|
||||
(type == Part::GeomBSplineCurve::getClassTypeId() && element==2) ? Sketcher_Element_BSpline_EndPoint :
|
||||
none,
|
||||
(type == Part::GeomPoint::getClassTypeId() && element==1) ? Sketcher_Element_Point_StartingPoint.getIcon(construction, false) :
|
||||
(type == Part::GeomLineSegment::getClassTypeId() && element==0) ? Sketcher_Element_Line_Edge.getIcon(construction, false) :
|
||||
(type == Part::GeomLineSegment::getClassTypeId() && element==1) ? Sketcher_Element_Line_StartingPoint.getIcon(construction, false) :
|
||||
(type == Part::GeomLineSegment::getClassTypeId() && element==2) ? Sketcher_Element_Line_EndPoint.getIcon(construction, false) :
|
||||
(type == Part::GeomArcOfCircle::getClassTypeId() && element==0) ? Sketcher_Element_Arc_Edge.getIcon(construction, false) :
|
||||
(type == Part::GeomArcOfCircle::getClassTypeId() && element==1) ? Sketcher_Element_Arc_StartingPoint.getIcon(construction, false) :
|
||||
(type == Part::GeomArcOfCircle::getClassTypeId() && element==2) ? Sketcher_Element_Arc_EndPoint.getIcon(construction, false) :
|
||||
(type == Part::GeomArcOfCircle::getClassTypeId() && element==3) ? Sketcher_Element_Arc_MidPoint.getIcon(construction, false) :
|
||||
(type == Part::GeomCircle::getClassTypeId() && element==0) ? Sketcher_Element_Circle_Edge.getIcon(construction, false) :
|
||||
(type == Part::GeomCircle::getClassTypeId() && element==3) ? Sketcher_Element_Circle_MidPoint.getIcon(construction, false) :
|
||||
(type == Part::GeomEllipse::getClassTypeId() && element==0) ? Sketcher_Element_Ellipse_Edge.getIcon(construction, false) :
|
||||
(type == Part::GeomEllipse::getClassTypeId() && element==3) ? Sketcher_Element_Ellipse_MidPoint.getIcon(construction, false) :
|
||||
(type == Part::GeomArcOfEllipse::getClassTypeId() && element==0) ? Sketcher_Element_ArcOfEllipse_Edge.getIcon(construction, false) :
|
||||
(type == Part::GeomArcOfEllipse::getClassTypeId() && element==1) ? Sketcher_Element_ArcOfEllipse_StartingPoint.getIcon(construction, false) :
|
||||
(type == Part::GeomArcOfEllipse::getClassTypeId() && element==2) ? Sketcher_Element_ArcOfEllipse_EndPoint.getIcon(construction, false) :
|
||||
(type == Part::GeomArcOfEllipse::getClassTypeId() && element==3) ? Sketcher_Element_ArcOfEllipse_MidPoint.getIcon(construction, false) :
|
||||
(type == Part::GeomArcOfHyperbola::getClassTypeId() && element==0) ? Sketcher_Element_ArcOfHyperbola_Edge.getIcon(construction, false) :
|
||||
(type == Part::GeomArcOfHyperbola::getClassTypeId() && element==1) ? Sketcher_Element_ArcOfHyperbola_StartingPoint.getIcon(construction, false) :
|
||||
(type == Part::GeomArcOfHyperbola::getClassTypeId() && element==2) ? Sketcher_Element_ArcOfHyperbola_EndPoint.getIcon(construction, false) :
|
||||
(type == Part::GeomArcOfHyperbola::getClassTypeId() && element==3) ? Sketcher_Element_ArcOfHyperbola_MidPoint.getIcon(construction, false) :
|
||||
(type == Part::GeomArcOfParabola::getClassTypeId() && element==0) ? Sketcher_Element_ArcOfParabola_Edge.getIcon(construction, false) :
|
||||
(type == Part::GeomArcOfParabola::getClassTypeId() && element==1) ? Sketcher_Element_ArcOfParabola_StartingPoint.getIcon(construction, false) :
|
||||
(type == Part::GeomArcOfParabola::getClassTypeId() && element==2) ? Sketcher_Element_ArcOfParabola_EndPoint.getIcon(construction, false) :
|
||||
(type == Part::GeomArcOfParabola::getClassTypeId() && element==3) ? Sketcher_Element_ArcOfParabola_MidPoint.getIcon(construction, false) :
|
||||
(type == Part::GeomBSplineCurve::getClassTypeId() && element==0) ? Sketcher_Element_BSpline_Edge.getIcon(construction, false) :
|
||||
(type == Part::GeomBSplineCurve::getClassTypeId() && element==1) ? Sketcher_Element_BSpline_StartingPoint.getIcon(construction, false) :
|
||||
(type == Part::GeomBSplineCurve::getClassTypeId() && element==2) ? Sketcher_Element_BSpline_EndPoint.getIcon(construction, false) :
|
||||
none.getIcon(construction, false),
|
||||
type == Part::GeomPoint::getClassTypeId() ? ( isNamingBoxChecked ?
|
||||
(tr("Point") + QString::fromLatin1("(Edge%1)").arg(i)):
|
||||
(QString::fromLatin1("%1-").arg(i)+tr("Point"))) :
|
||||
@@ -813,34 +815,34 @@ void TaskSketcherElements::slotElementsChanged(void)
|
||||
|
||||
|
||||
ui->listWidgetElements->addItem(new ElementItem(
|
||||
(type == Part::GeomPoint::getClassTypeId() && element==1) ? Sketcher_Element_Point_StartingPoint :
|
||||
(type == Part::GeomLineSegment::getClassTypeId() && element==0) ? Sketcher_Element_Line_Edge :
|
||||
(type == Part::GeomLineSegment::getClassTypeId() && element==1) ? Sketcher_Element_Line_StartingPoint :
|
||||
(type == Part::GeomLineSegment::getClassTypeId() && element==2) ? Sketcher_Element_Line_EndPoint :
|
||||
(type == Part::GeomArcOfCircle::getClassTypeId() && element==0) ? Sketcher_Element_Arc_Edge :
|
||||
(type == Part::GeomArcOfCircle::getClassTypeId() && element==1) ? Sketcher_Element_Arc_StartingPoint :
|
||||
(type == Part::GeomArcOfCircle::getClassTypeId() && element==2) ? Sketcher_Element_Arc_EndPoint :
|
||||
(type == Part::GeomArcOfCircle::getClassTypeId() && element==3) ? Sketcher_Element_Arc_MidPoint :
|
||||
(type == Part::GeomCircle::getClassTypeId() && element==0) ? Sketcher_Element_Circle_Edge :
|
||||
(type == Part::GeomCircle::getClassTypeId() && element==3) ? Sketcher_Element_Circle_MidPoint :
|
||||
(type == Part::GeomEllipse::getClassTypeId() && element==0) ? Sketcher_Element_Ellipse_Edge :
|
||||
(type == Part::GeomEllipse::getClassTypeId() && element==3) ? Sketcher_Element_Ellipse_MidPoint :
|
||||
(type == Part::GeomArcOfEllipse::getClassTypeId() && element==0) ? Sketcher_Element_ArcOfEllipse_Edge :
|
||||
(type == Part::GeomArcOfEllipse::getClassTypeId() && element==1) ? Sketcher_Element_ArcOfEllipse_StartingPoint :
|
||||
(type == Part::GeomArcOfEllipse::getClassTypeId() && element==2) ? Sketcher_Element_ArcOfEllipse_EndPoint :
|
||||
(type == Part::GeomArcOfEllipse::getClassTypeId() && element==3) ? Sketcher_Element_ArcOfEllipse_MidPoint :
|
||||
(type == Part::GeomArcOfHyperbola::getClassTypeId() && element==0) ? Sketcher_Element_ArcOfHyperbola_Edge :
|
||||
(type == Part::GeomArcOfHyperbola::getClassTypeId() && element==1) ? Sketcher_Element_ArcOfHyperbola_StartingPoint :
|
||||
(type == Part::GeomArcOfHyperbola::getClassTypeId() && element==2) ? Sketcher_Element_ArcOfHyperbola_EndPoint :
|
||||
(type == Part::GeomArcOfHyperbola::getClassTypeId() && element==3) ? Sketcher_Element_ArcOfHyperbola_MidPoint :
|
||||
(type == Part::GeomArcOfParabola::getClassTypeId() && element==0) ? Sketcher_Element_ArcOfParabola_Edge :
|
||||
(type == Part::GeomArcOfParabola::getClassTypeId() && element==1) ? Sketcher_Element_ArcOfParabola_StartingPoint :
|
||||
(type == Part::GeomArcOfParabola::getClassTypeId() && element==2) ? Sketcher_Element_ArcOfParabola_EndPoint :
|
||||
(type == Part::GeomArcOfParabola::getClassTypeId() && element==3) ? Sketcher_Element_ArcOfParabola_MidPoint :
|
||||
(type == Part::GeomBSplineCurve::getClassTypeId() && element==0) ? Sketcher_Element_BSpline_Edge :
|
||||
(type == Part::GeomBSplineCurve::getClassTypeId() && element==1) ? Sketcher_Element_BSpline_StartingPoint :
|
||||
(type == Part::GeomBSplineCurve::getClassTypeId() && element==2) ? Sketcher_Element_BSpline_EndPoint :
|
||||
none,
|
||||
(type == Part::GeomPoint::getClassTypeId() && element==1) ? Sketcher_Element_Point_StartingPoint.External :
|
||||
(type == Part::GeomLineSegment::getClassTypeId() && element==0) ? Sketcher_Element_Line_Edge.External :
|
||||
(type == Part::GeomLineSegment::getClassTypeId() && element==1) ? Sketcher_Element_Line_StartingPoint.External :
|
||||
(type == Part::GeomLineSegment::getClassTypeId() && element==2) ? Sketcher_Element_Line_EndPoint.External :
|
||||
(type == Part::GeomArcOfCircle::getClassTypeId() && element==0) ? Sketcher_Element_Arc_Edge.External :
|
||||
(type == Part::GeomArcOfCircle::getClassTypeId() && element==1) ? Sketcher_Element_Arc_StartingPoint.External :
|
||||
(type == Part::GeomArcOfCircle::getClassTypeId() && element==2) ? Sketcher_Element_Arc_EndPoint.External :
|
||||
(type == Part::GeomArcOfCircle::getClassTypeId() && element==3) ? Sketcher_Element_Arc_MidPoint.External :
|
||||
(type == Part::GeomCircle::getClassTypeId() && element==0) ? Sketcher_Element_Circle_Edge.External :
|
||||
(type == Part::GeomCircle::getClassTypeId() && element==3) ? Sketcher_Element_Circle_MidPoint.External :
|
||||
(type == Part::GeomEllipse::getClassTypeId() && element==0) ? Sketcher_Element_Ellipse_Edge.External :
|
||||
(type == Part::GeomEllipse::getClassTypeId() && element==3) ? Sketcher_Element_Ellipse_MidPoint.External :
|
||||
(type == Part::GeomArcOfEllipse::getClassTypeId() && element==0) ? Sketcher_Element_ArcOfEllipse_Edge.External :
|
||||
(type == Part::GeomArcOfEllipse::getClassTypeId() && element==1) ? Sketcher_Element_ArcOfEllipse_StartingPoint.External :
|
||||
(type == Part::GeomArcOfEllipse::getClassTypeId() && element==2) ? Sketcher_Element_ArcOfEllipse_EndPoint.External :
|
||||
(type == Part::GeomArcOfEllipse::getClassTypeId() && element==3) ? Sketcher_Element_ArcOfEllipse_MidPoint.External :
|
||||
(type == Part::GeomArcOfHyperbola::getClassTypeId() && element==0) ? Sketcher_Element_ArcOfHyperbola_Edge.External :
|
||||
(type == Part::GeomArcOfHyperbola::getClassTypeId() && element==1) ? Sketcher_Element_ArcOfHyperbola_StartingPoint.External :
|
||||
(type == Part::GeomArcOfHyperbola::getClassTypeId() && element==2) ? Sketcher_Element_ArcOfHyperbola_EndPoint.External :
|
||||
(type == Part::GeomArcOfHyperbola::getClassTypeId() && element==3) ? Sketcher_Element_ArcOfHyperbola_MidPoint.External :
|
||||
(type == Part::GeomArcOfParabola::getClassTypeId() && element==0) ? Sketcher_Element_ArcOfParabola_Edge.External :
|
||||
(type == Part::GeomArcOfParabola::getClassTypeId() && element==1) ? Sketcher_Element_ArcOfParabola_StartingPoint.External :
|
||||
(type == Part::GeomArcOfParabola::getClassTypeId() && element==2) ? Sketcher_Element_ArcOfParabola_EndPoint.External :
|
||||
(type == Part::GeomArcOfParabola::getClassTypeId() && element==3) ? Sketcher_Element_ArcOfParabola_MidPoint.External :
|
||||
(type == Part::GeomBSplineCurve::getClassTypeId() && element==0) ? Sketcher_Element_BSpline_Edge.External :
|
||||
(type == Part::GeomBSplineCurve::getClassTypeId() && element==1) ? Sketcher_Element_BSpline_StartingPoint.External :
|
||||
(type == Part::GeomBSplineCurve::getClassTypeId() && element==2) ? Sketcher_Element_BSpline_EndPoint.External :
|
||||
none.External,
|
||||
type == Part::GeomPoint::getClassTypeId() ? ( isNamingBoxChecked ?
|
||||
(tr("Point") + linkname):
|
||||
(QString::fromLatin1("%1-").arg(i-2)+tr("Point"))) :
|
||||
@@ -1033,67 +1035,70 @@ void TaskSketcherElements::updateVisibility(int filterindex)
|
||||
|
||||
void TaskSketcherElements::updateIcons(int element)
|
||||
{
|
||||
QIcon Sketcher_Element_Arc_Edge( Gui::BitmapFactory().iconFromTheme("Sketcher_Element_Arc_Edge") );
|
||||
QIcon Sketcher_Element_Arc_EndPoint( Gui::BitmapFactory().iconFromTheme("Sketcher_Element_Arc_EndPoint") );
|
||||
QIcon Sketcher_Element_Arc_MidPoint( Gui::BitmapFactory().iconFromTheme("Sketcher_Element_Arc_MidPoint") );
|
||||
QIcon Sketcher_Element_Arc_StartingPoint( Gui::BitmapFactory().iconFromTheme("Sketcher_Element_Arc_StartingPoint") );
|
||||
QIcon Sketcher_Element_Circle_Edge( Gui::BitmapFactory().iconFromTheme("Sketcher_Element_Circle_Edge") );
|
||||
QIcon Sketcher_Element_Circle_MidPoint( Gui::BitmapFactory().iconFromTheme("Sketcher_Element_Circle_MidPoint") );
|
||||
QIcon Sketcher_Element_Line_Edge( Gui::BitmapFactory().iconFromTheme("Sketcher_Element_Line_Edge") );
|
||||
QIcon Sketcher_Element_Line_EndPoint( Gui::BitmapFactory().iconFromTheme("Sketcher_Element_Line_EndPoint") );
|
||||
QIcon Sketcher_Element_Line_StartingPoint( Gui::BitmapFactory().iconFromTheme("Sketcher_Element_Line_StartingPoint") );
|
||||
QIcon Sketcher_Element_Point_StartingPoint( Gui::BitmapFactory().iconFromTheme("Sketcher_Element_Point_StartingPoint") );
|
||||
QIcon Sketcher_Element_Ellipse_Edge( Gui::BitmapFactory().iconFromTheme("Sketcher_Element_Ellipse_Edge_2") );
|
||||
QIcon Sketcher_Element_Ellipse_MidPoint( Gui::BitmapFactory().iconFromTheme("Sketcher_Element_Ellipse_CentrePoint") );
|
||||
QIcon Sketcher_Element_ArcOfEllipse_Edge( Gui::BitmapFactory().iconFromTheme("Sketcher_Element_Elliptical_Arc_Edge") );
|
||||
QIcon Sketcher_Element_ArcOfEllipse_MidPoint( Gui::BitmapFactory().iconFromTheme("Sketcher_Element_Elliptical_Arc_Centre_Point") );
|
||||
QIcon Sketcher_Element_ArcOfEllipse_StartingPoint( Gui::BitmapFactory().iconFromTheme("Sketcher_Element_Elliptical_Arc_Start_Point") );
|
||||
QIcon Sketcher_Element_ArcOfEllipse_EndPoint( Gui::BitmapFactory().iconFromTheme("Sketcher_Element_Elliptical_Arc_End_Point") );
|
||||
QIcon Sketcher_Element_ArcOfHyperbola_Edge( Gui::BitmapFactory().iconFromTheme("Sketcher_Element_Hyperbolic_Arc_Edge") );
|
||||
QIcon Sketcher_Element_ArcOfHyperbola_MidPoint( Gui::BitmapFactory().iconFromTheme("Sketcher_Element_Hyperbolic_Arc_Centre_Point") );
|
||||
QIcon Sketcher_Element_ArcOfHyperbola_StartingPoint( Gui::BitmapFactory().iconFromTheme("Sketcher_Element_Hyperbolic_Arc_Start_Point") );
|
||||
QIcon Sketcher_Element_ArcOfHyperbola_EndPoint( Gui::BitmapFactory().iconFromTheme("Sketcher_Element_Hyperbolic_Arc_End_Point") );
|
||||
QIcon Sketcher_Element_ArcOfParabola_Edge( Gui::BitmapFactory().iconFromTheme("Sketcher_Element_Parabolic_Arc_Edge") );
|
||||
QIcon Sketcher_Element_ArcOfParabola_MidPoint( Gui::BitmapFactory().iconFromTheme("Sketcher_Element_Parabolic_Arc_Centre_Point") );
|
||||
QIcon Sketcher_Element_ArcOfParabola_StartingPoint( Gui::BitmapFactory().iconFromTheme("Sketcher_Element_Parabolic_Arc_Start_Point") );
|
||||
QIcon Sketcher_Element_ArcOfParabola_EndPoint( Gui::BitmapFactory().iconFromTheme("Sketcher_Element_Parabolic_Arc_End_Point") );
|
||||
QIcon Sketcher_Element_BSpline_Edge( Gui::BitmapFactory().iconFromTheme("Sketcher_Element_BSpline_Edge") );
|
||||
QIcon Sketcher_Element_BSpline_StartingPoint( Gui::BitmapFactory().iconFromTheme("Sketcher_Element_BSpline_StartPoint") );
|
||||
QIcon Sketcher_Element_BSpline_EndPoint( Gui::BitmapFactory().iconFromTheme("Sketcher_Element_BSpline_EndPoint") );
|
||||
QIcon none( Gui::BitmapFactory().iconFromTheme("Sketcher_Element_SelectionTypeInvalid") );
|
||||
MultIcon Sketcher_Element_Arc_Edge("Sketcher_Element_Arc_Edge");
|
||||
MultIcon Sketcher_Element_Arc_EndPoint("Sketcher_Element_Arc_EndPoint");
|
||||
MultIcon Sketcher_Element_Arc_MidPoint("Sketcher_Element_Arc_MidPoint");
|
||||
MultIcon Sketcher_Element_Arc_StartingPoint("Sketcher_Element_Arc_StartingPoint");
|
||||
MultIcon Sketcher_Element_Circle_Edge("Sketcher_Element_Circle_Edge");
|
||||
MultIcon Sketcher_Element_Circle_MidPoint("Sketcher_Element_Circle_MidPoint");
|
||||
MultIcon Sketcher_Element_Line_Edge("Sketcher_Element_Line_Edge");
|
||||
MultIcon Sketcher_Element_Line_EndPoint("Sketcher_Element_Line_EndPoint");
|
||||
MultIcon Sketcher_Element_Line_StartingPoint("Sketcher_Element_Line_StartingPoint");
|
||||
MultIcon Sketcher_Element_Point_StartingPoint("Sketcher_Element_Point_StartingPoint");
|
||||
MultIcon Sketcher_Element_Ellipse_Edge("Sketcher_Element_Ellipse_Edge_2");
|
||||
MultIcon Sketcher_Element_Ellipse_MidPoint("Sketcher_Element_Ellipse_CentrePoint");
|
||||
MultIcon Sketcher_Element_ArcOfEllipse_Edge("Sketcher_Element_Elliptical_Arc_Edge");
|
||||
MultIcon Sketcher_Element_ArcOfEllipse_MidPoint("Sketcher_Element_Elliptical_Arc_Centre_Point");
|
||||
MultIcon Sketcher_Element_ArcOfEllipse_StartingPoint("Sketcher_Element_Elliptical_Arc_Start_Point");
|
||||
MultIcon Sketcher_Element_ArcOfEllipse_EndPoint("Sketcher_Element_Elliptical_Arc_End_Point");
|
||||
MultIcon Sketcher_Element_ArcOfHyperbola_Edge("Sketcher_Element_Hyperbolic_Arc_Edge");
|
||||
MultIcon Sketcher_Element_ArcOfHyperbola_MidPoint("Sketcher_Element_Hyperbolic_Arc_Centre_Point");
|
||||
MultIcon Sketcher_Element_ArcOfHyperbola_StartingPoint("Sketcher_Element_Hyperbolic_Arc_Start_Point");
|
||||
MultIcon Sketcher_Element_ArcOfHyperbola_EndPoint("Sketcher_Element_Hyperbolic_Arc_End_Point");
|
||||
MultIcon Sketcher_Element_ArcOfParabola_Edge("Sketcher_Element_Parabolic_Arc_Edge");
|
||||
MultIcon Sketcher_Element_ArcOfParabola_MidPoint("Sketcher_Element_Parabolic_Arc_Centre_Point");
|
||||
MultIcon Sketcher_Element_ArcOfParabola_StartingPoint("Sketcher_Element_Parabolic_Arc_Start_Point");
|
||||
MultIcon Sketcher_Element_ArcOfParabola_EndPoint("Sketcher_Element_Parabolic_Arc_End_Point");
|
||||
MultIcon Sketcher_Element_BSpline_Edge("Sketcher_Element_BSpline_Edge");
|
||||
MultIcon Sketcher_Element_BSpline_StartingPoint("Sketcher_Element_BSpline_StartPoint");
|
||||
MultIcon Sketcher_Element_BSpline_EndPoint("Sketcher_Element_BSpline_EndPoint");
|
||||
MultIcon none("Sketcher_Element_SelectionTypeInvalid");
|
||||
|
||||
|
||||
for (int i=0;i<ui->listWidgetElements->count(); i++) {
|
||||
Base::Type type = static_cast<ElementItem *>(ui->listWidgetElements->item(i))->GeometryType;
|
||||
|
||||
bool construction = static_cast<ElementItem *>(ui->listWidgetElements->item(i))->isConstruction;
|
||||
bool external = static_cast<ElementItem *>(ui->listWidgetElements->item(i))->isExternal;
|
||||
|
||||
ui->listWidgetElements->item(i)->setIcon(
|
||||
(type == Part::GeomPoint::getClassTypeId() && element==1) ? Sketcher_Element_Point_StartingPoint :
|
||||
(type == Part::GeomLineSegment::getClassTypeId() && element==0) ? Sketcher_Element_Line_Edge :
|
||||
(type == Part::GeomLineSegment::getClassTypeId() && element==1) ? Sketcher_Element_Line_StartingPoint :
|
||||
(type == Part::GeomLineSegment::getClassTypeId() && element==2) ? Sketcher_Element_Line_EndPoint :
|
||||
(type == Part::GeomArcOfCircle::getClassTypeId() && element==0) ? Sketcher_Element_Arc_Edge :
|
||||
(type == Part::GeomArcOfCircle::getClassTypeId() && element==1) ? Sketcher_Element_Arc_StartingPoint :
|
||||
(type == Part::GeomArcOfCircle::getClassTypeId() && element==2) ? Sketcher_Element_Arc_EndPoint :
|
||||
(type == Part::GeomArcOfCircle::getClassTypeId() && element==3) ? Sketcher_Element_Arc_MidPoint :
|
||||
(type == Part::GeomCircle::getClassTypeId() && element==0) ? Sketcher_Element_Circle_Edge :
|
||||
(type == Part::GeomCircle::getClassTypeId() && element==3) ? Sketcher_Element_Circle_MidPoint :
|
||||
(type == Part::GeomEllipse::getClassTypeId() && element==0) ? Sketcher_Element_Ellipse_Edge :
|
||||
(type == Part::GeomEllipse::getClassTypeId() && element==3) ? Sketcher_Element_Ellipse_MidPoint :
|
||||
(type == Part::GeomArcOfEllipse::getClassTypeId() && element==0) ? Sketcher_Element_ArcOfEllipse_Edge :
|
||||
(type == Part::GeomArcOfEllipse::getClassTypeId() && element==1) ? Sketcher_Element_ArcOfEllipse_StartingPoint :
|
||||
(type == Part::GeomArcOfEllipse::getClassTypeId() && element==2) ? Sketcher_Element_ArcOfEllipse_EndPoint :
|
||||
(type == Part::GeomArcOfEllipse::getClassTypeId() && element==3) ? Sketcher_Element_ArcOfEllipse_MidPoint :
|
||||
(type == Part::GeomArcOfHyperbola::getClassTypeId() && element==0) ? Sketcher_Element_ArcOfHyperbola_Edge :
|
||||
(type == Part::GeomArcOfHyperbola::getClassTypeId() && element==1) ? Sketcher_Element_ArcOfHyperbola_StartingPoint :
|
||||
(type == Part::GeomArcOfHyperbola::getClassTypeId() && element==2) ? Sketcher_Element_ArcOfHyperbola_EndPoint :
|
||||
(type == Part::GeomArcOfHyperbola::getClassTypeId() && element==3) ? Sketcher_Element_ArcOfHyperbola_MidPoint :
|
||||
(type == Part::GeomArcOfParabola::getClassTypeId() && element==0) ? Sketcher_Element_ArcOfParabola_Edge :
|
||||
(type == Part::GeomArcOfParabola::getClassTypeId() && element==1) ? Sketcher_Element_ArcOfParabola_StartingPoint :
|
||||
(type == Part::GeomArcOfParabola::getClassTypeId() && element==2) ? Sketcher_Element_ArcOfParabola_EndPoint :
|
||||
(type == Part::GeomArcOfParabola::getClassTypeId() && element==3) ? Sketcher_Element_ArcOfParabola_MidPoint :
|
||||
(type == Part::GeomBSplineCurve::getClassTypeId() && element==0) ? Sketcher_Element_BSpline_Edge :
|
||||
(type == Part::GeomBSplineCurve::getClassTypeId() && element==1) ? Sketcher_Element_BSpline_StartingPoint :
|
||||
(type == Part::GeomBSplineCurve::getClassTypeId() && element==2) ? Sketcher_Element_BSpline_EndPoint :
|
||||
none);
|
||||
(type == Part::GeomPoint::getClassTypeId() && element==1) ? Sketcher_Element_Point_StartingPoint.getIcon(construction, external) :
|
||||
(type == Part::GeomLineSegment::getClassTypeId() && element==0) ? Sketcher_Element_Line_Edge.getIcon(construction, external) :
|
||||
(type == Part::GeomLineSegment::getClassTypeId() && element==1) ? Sketcher_Element_Line_StartingPoint.getIcon(construction, external) :
|
||||
(type == Part::GeomLineSegment::getClassTypeId() && element==2) ? Sketcher_Element_Line_EndPoint.getIcon(construction, external) :
|
||||
(type == Part::GeomArcOfCircle::getClassTypeId() && element==0) ? Sketcher_Element_Arc_Edge.getIcon(construction, external) :
|
||||
(type == Part::GeomArcOfCircle::getClassTypeId() && element==1) ? Sketcher_Element_Arc_StartingPoint.getIcon(construction, external) :
|
||||
(type == Part::GeomArcOfCircle::getClassTypeId() && element==2) ? Sketcher_Element_Arc_EndPoint.getIcon(construction, external) :
|
||||
(type == Part::GeomArcOfCircle::getClassTypeId() && element==3) ? Sketcher_Element_Arc_MidPoint.getIcon(construction, external) :
|
||||
(type == Part::GeomCircle::getClassTypeId() && element==0) ? Sketcher_Element_Circle_Edge.getIcon(construction, external) :
|
||||
(type == Part::GeomCircle::getClassTypeId() && element==3) ? Sketcher_Element_Circle_MidPoint.getIcon(construction, external) :
|
||||
(type == Part::GeomEllipse::getClassTypeId() && element==0) ? Sketcher_Element_Ellipse_Edge.getIcon(construction, external) :
|
||||
(type == Part::GeomEllipse::getClassTypeId() && element==3) ? Sketcher_Element_Ellipse_MidPoint.getIcon(construction, external) :
|
||||
(type == Part::GeomArcOfEllipse::getClassTypeId() && element==0) ? Sketcher_Element_ArcOfEllipse_Edge.getIcon(construction, external) :
|
||||
(type == Part::GeomArcOfEllipse::getClassTypeId() && element==1) ? Sketcher_Element_ArcOfEllipse_StartingPoint.getIcon(construction, external) :
|
||||
(type == Part::GeomArcOfEllipse::getClassTypeId() && element==2) ? Sketcher_Element_ArcOfEllipse_EndPoint.getIcon(construction, external) :
|
||||
(type == Part::GeomArcOfEllipse::getClassTypeId() && element==3) ? Sketcher_Element_ArcOfEllipse_MidPoint.getIcon(construction, external) :
|
||||
(type == Part::GeomArcOfHyperbola::getClassTypeId() && element==0) ? Sketcher_Element_ArcOfHyperbola_Edge.getIcon(construction, external) :
|
||||
(type == Part::GeomArcOfHyperbola::getClassTypeId() && element==1) ? Sketcher_Element_ArcOfHyperbola_StartingPoint.getIcon(construction, external) :
|
||||
(type == Part::GeomArcOfHyperbola::getClassTypeId() && element==2) ? Sketcher_Element_ArcOfHyperbola_EndPoint.getIcon(construction, external) :
|
||||
(type == Part::GeomArcOfHyperbola::getClassTypeId() && element==3) ? Sketcher_Element_ArcOfHyperbola_MidPoint.getIcon(construction, external) :
|
||||
(type == Part::GeomArcOfParabola::getClassTypeId() && element==0) ? Sketcher_Element_ArcOfParabola_Edge.getIcon(construction, external) :
|
||||
(type == Part::GeomArcOfParabola::getClassTypeId() && element==1) ? Sketcher_Element_ArcOfParabola_StartingPoint.getIcon(construction, external) :
|
||||
(type == Part::GeomArcOfParabola::getClassTypeId() && element==2) ? Sketcher_Element_ArcOfParabola_EndPoint.getIcon(construction, external) :
|
||||
(type == Part::GeomArcOfParabola::getClassTypeId() && element==3) ? Sketcher_Element_ArcOfParabola_MidPoint.getIcon(construction, external) :
|
||||
(type == Part::GeomBSplineCurve::getClassTypeId() && element==0) ? Sketcher_Element_BSpline_Edge.getIcon(construction, external) :
|
||||
(type == Part::GeomBSplineCurve::getClassTypeId() && element==1) ? Sketcher_Element_BSpline_StartingPoint.getIcon(construction, external) :
|
||||
(type == Part::GeomBSplineCurve::getClassTypeId() && element==2) ? Sketcher_Element_BSpline_EndPoint.getIcon(construction, external) :
|
||||
none.getIcon(construction, external));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1105,6 +1110,45 @@ void TaskSketcherElements::changeEvent(QEvent *e)
|
||||
}
|
||||
}
|
||||
|
||||
TaskSketcherElements::MultIcon::MultIcon(const char* name)
|
||||
{
|
||||
int hue, sat, val, alp;
|
||||
Normal = Gui::BitmapFactory().iconFromTheme(name);
|
||||
QImage imgConstr(Normal.pixmap(Normal.availableSizes()[0]).toImage());
|
||||
QImage imgExt(imgConstr);
|
||||
|
||||
for(int ix=0 ; ix<imgConstr.width() ; ix++) {
|
||||
for(int iy=0 ; iy<imgConstr.height() ; iy++) {
|
||||
QColor clr = QColor::fromRgba(imgConstr.pixel(ix,iy));
|
||||
clr.getHsv(&hue, &sat, &val, &alp);
|
||||
if (alp > 127 && hue >= 0) {
|
||||
if (sat > 127 && (hue > 330 || hue < 30)) {
|
||||
clr.setHsv((hue + 240) % 360, sat, val, alp);
|
||||
imgConstr.setPixel(ix, iy, clr.rgba());
|
||||
clr.setHsv((hue + 300) % 360, sat, val, alp);
|
||||
imgExt.setPixel(ix, iy, clr.rgba());
|
||||
}
|
||||
else if (sat < 64 && val > 192)
|
||||
{
|
||||
clr.setHsv(240, (255-sat), val, alp);
|
||||
imgConstr.setPixel(ix, iy, clr.rgba());
|
||||
clr.setHsv(300, (255-sat), val, alp);
|
||||
imgExt.setPixel(ix, iy, clr.rgba());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Construction = QIcon(QPixmap::fromImage(imgConstr));
|
||||
External = QIcon(QPixmap::fromImage(imgExt));
|
||||
|
||||
}
|
||||
|
||||
QIcon TaskSketcherElements::MultIcon::getIcon(bool construction, bool external) const
|
||||
{
|
||||
if (construction && external) return QIcon();
|
||||
if (construction) return Construction;
|
||||
if (external) return External;
|
||||
return Normal;
|
||||
}
|
||||
|
||||
#include "moc_TaskSketcherElements.cpp"
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <Gui/Selection.h>
|
||||
#include <boost/signals2.hpp>
|
||||
#include <QListWidget>
|
||||
#include <QIcon>
|
||||
|
||||
namespace App {
|
||||
class Property;
|
||||
@@ -91,6 +92,18 @@ class TaskSketcherElements : public Gui::TaskView::TaskBox, public Gui::Selectio
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
class MultIcon {
|
||||
|
||||
public:
|
||||
MultIcon(const char*);
|
||||
|
||||
QIcon Normal;
|
||||
QIcon Construction;
|
||||
QIcon External;
|
||||
|
||||
QIcon getIcon(bool construction, bool external) const;
|
||||
};
|
||||
|
||||
public:
|
||||
TaskSketcherElements(ViewProviderSketch *sketchView);
|
||||
~TaskSketcherElements();
|
||||
|
||||
@@ -1067,7 +1067,7 @@ void PropertySheet::removeDependencies(CellAddress key)
|
||||
void PropertySheet::recomputeDependants(const App::DocumentObject *owner, const char *propName)
|
||||
{
|
||||
// First, search without actual property name for sub-object/link
|
||||
// references, i.e indirect references. The depenedecies of these
|
||||
// references, i.e indirect references. The dependencies of these
|
||||
// references are too complex to track exactly, so we only track the
|
||||
// top parent object instead, and mark the involved expression
|
||||
// whenever the top parent changes.
|
||||
|
||||
@@ -570,6 +570,13 @@ Base::Vector3d DrawUtil::invertY(Base::Vector3d v)
|
||||
return result;
|
||||
}
|
||||
|
||||
QPointF DrawUtil::invertY(QPointF v)
|
||||
{
|
||||
QPointF result(v.x(), -v.y());
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
//obs? was used in CSV prototype of Cosmetics
|
||||
std::vector<std::string> DrawUtil::split(std::string csvLine)
|
||||
{
|
||||
|
||||
@@ -110,6 +110,7 @@ class TechDrawExport DrawUtil {
|
||||
static std::string shapeToString(TopoDS_Shape s);
|
||||
static TopoDS_Shape shapeFromString(std::string s);
|
||||
static Base::Vector3d invertY(Base::Vector3d v);
|
||||
static QPointF invertY(QPointF p);
|
||||
static std::vector<std::string> split(std::string csvLine);
|
||||
static std::vector<std::string> tokenize(std::string csvLine, std::string delimiter = ",$$$,");
|
||||
static App::Color pyTupleToColor(PyObject* pColor);
|
||||
|
||||
@@ -100,8 +100,6 @@ using namespace std;
|
||||
PROPERTY_SOURCE(TechDraw::DrawViewDetail, TechDraw::DrawViewPart)
|
||||
|
||||
DrawViewDetail::DrawViewDetail()
|
||||
// :
|
||||
// m_mattingStyle(0)
|
||||
{
|
||||
static const char *dgroup = "Detail";
|
||||
|
||||
|
||||
@@ -70,6 +70,8 @@ set(TechDrawGui_MOC_HDRS
|
||||
QGIWeldSymbol.h
|
||||
SymbolChooser.h
|
||||
TaskActiveView.h
|
||||
TaskDetail.h
|
||||
QGIGhostHighlight.h
|
||||
)
|
||||
|
||||
fc_wrap_cpp(TechDrawGui_MOC_SRCS ${TechDrawGui_MOC_HDRS})
|
||||
@@ -103,6 +105,7 @@ set(TechDrawGui_UIC_SRCS
|
||||
TaskWeldingSymbol.ui
|
||||
SymbolChooser.ui
|
||||
TaskActiveView.ui
|
||||
TaskDetail.ui
|
||||
)
|
||||
|
||||
if(BUILD_QT5)
|
||||
@@ -203,6 +206,9 @@ SET(TechDrawGui_SRCS
|
||||
TaskActiveView.h
|
||||
Grabber3d.cpp
|
||||
Grabber3d.h
|
||||
TaskDetail.ui
|
||||
TaskDetail.cpp
|
||||
TaskDetail.h
|
||||
)
|
||||
|
||||
SET(TechDrawGuiView_SRCS
|
||||
@@ -299,6 +305,8 @@ SET(TechDrawGuiView_SRCS
|
||||
TemplateTextField.cpp
|
||||
TemplateTextField.h
|
||||
ZVALUE.h
|
||||
QGIGhostHighlight.cpp
|
||||
QGIGhostHighlight.h
|
||||
)
|
||||
SET(TechDrawGuiViewProvider_SRCS
|
||||
ViewProviderPage.cpp
|
||||
@@ -366,6 +374,7 @@ SET(TechDrawGuiTaskDlgs_SRCS
|
||||
TaskWeldingSymbol.ui
|
||||
SymbolChooser.ui
|
||||
TaskActiveView.ui
|
||||
TaskDetail.ui
|
||||
)
|
||||
SOURCE_GROUP("TaskDialogs" FILES ${TechDrawGuiTaskDlgs_SRCS})
|
||||
|
||||
|
||||
+1378
-1392
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,115 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2020 WandererFan <wandererfan@gmail.com> *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#ifndef _PreComp_
|
||||
#include <QPainter>
|
||||
#include <QPainterPathStroker>
|
||||
#include <QStyleOptionGraphicsItem>
|
||||
#include <QPen>
|
||||
#include <QColor>
|
||||
#endif
|
||||
|
||||
#include <App/Application.h>
|
||||
#include <App/Material.h>
|
||||
#include <Base/Console.h>
|
||||
#include <Base/Parameter.h>
|
||||
|
||||
#include <Mod/TechDraw/App/DrawUtil.h>
|
||||
|
||||
#include <qmath.h>
|
||||
#include "Rez.h"
|
||||
#include "DrawGuiUtil.h"
|
||||
#include "QGIView.h"
|
||||
#include "QGIGhostHighlight.h"
|
||||
|
||||
using namespace TechDrawGui;
|
||||
using namespace TechDraw;
|
||||
|
||||
QGIGhostHighlight::QGIGhostHighlight()
|
||||
{
|
||||
setInteractive(true);
|
||||
m_dragging = false;
|
||||
|
||||
//make the ghost very visible
|
||||
QFont f(QGIView::getPrefFont());
|
||||
double fontSize = QGIView::getPrefFontSize();
|
||||
setFont(f, fontSize);
|
||||
setReference("drag");
|
||||
setStyle(Qt::SolidLine);
|
||||
setColor(prefSelectColor());
|
||||
setWidth(Rez::guiX(1.0));
|
||||
setRadius(10.0); //placeholder
|
||||
}
|
||||
|
||||
QGIGhostHighlight::~QGIGhostHighlight()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QVariant QGIGhostHighlight::itemChange(GraphicsItemChange change, const QVariant &value)
|
||||
{
|
||||
if (change == ItemPositionHasChanged && scene()) {
|
||||
// nothing to do here?
|
||||
}
|
||||
return QGIHighlight::itemChange(change, value);
|
||||
}
|
||||
|
||||
void QGIGhostHighlight::mousePressEvent(QGraphicsSceneMouseEvent * event)
|
||||
{
|
||||
// Base::Console().Message("QGIGhostHighlight::mousePress() - %X\n", this);
|
||||
if ( (event->button() == Qt::LeftButton) &&
|
||||
(flags() && QGraphicsItem::ItemIsMovable) ) {
|
||||
m_dragging = true;
|
||||
event->accept();
|
||||
}
|
||||
QGIHighlight::mousePressEvent(event);
|
||||
}
|
||||
|
||||
void QGIGhostHighlight::mouseReleaseEvent(QGraphicsSceneMouseEvent * event)
|
||||
{
|
||||
// Base::Console().Message("QGIGhostHighlight::mouseRelease() - pos: %s scenePos: %s\n",
|
||||
// DrawUtil::formatVector(pos()).c_str(),
|
||||
// DrawUtil::formatVector(mapToScene(pos())).c_str());
|
||||
if (m_dragging) {
|
||||
m_dragging = false;
|
||||
Q_EMIT positionChange(scenePos());
|
||||
event->accept();
|
||||
}
|
||||
QGIHighlight::mouseReleaseEvent(event);
|
||||
}
|
||||
|
||||
void QGIGhostHighlight::setInteractive(bool state)
|
||||
{
|
||||
setFlag(QGraphicsItem::ItemIsSelectable, state);
|
||||
setFlag(QGraphicsItem::ItemIsMovable, state);
|
||||
setFlag(QGraphicsItem::ItemSendsScenePositionChanges, state);
|
||||
setFlag(QGraphicsItem::ItemSendsGeometryChanges, state);
|
||||
}
|
||||
|
||||
//radius should scaled, but not Rez::guix()
|
||||
void QGIGhostHighlight::setRadius(double r)
|
||||
{
|
||||
setBounds(-r, r, r, -r);
|
||||
}
|
||||
|
||||
#include <Mod/TechDraw/Gui/moc_QGIGhostHighlight.cpp>
|
||||
@@ -0,0 +1,66 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2020 WandererFan <wandererfan@gmail.com> *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef TECHDRAWGUI_QGIGHOSTHIGHLIGHT_H
|
||||
#define TECHDRAWGUI_QGIGHOSTHIGHLIGHT_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QGraphicsScene>
|
||||
#include <QGraphicsSceneEvent>
|
||||
#include <QPointF>
|
||||
|
||||
#include "QGIHighlight.h"
|
||||
|
||||
//a movable, selectable surrogate for detail highlights in QGIVPart
|
||||
|
||||
namespace TechDrawGui
|
||||
{
|
||||
|
||||
class TechDrawGuiExport QGIGhostHighlight : public QObject, public QGIHighlight
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit QGIGhostHighlight();
|
||||
~QGIGhostHighlight();
|
||||
|
||||
enum {Type = QGraphicsItem::UserType + 177};
|
||||
int type() const { return Type;}
|
||||
|
||||
void setInteractive(bool state);
|
||||
void setRadius(double r);
|
||||
|
||||
Q_SIGNALS:
|
||||
void positionChange(QPointF p);
|
||||
|
||||
protected:
|
||||
virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value) override;
|
||||
virtual void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
|
||||
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
|
||||
|
||||
bool m_dragging;
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // TECHDRAWGUI_QGIGHOSTHIGHLIGHT_H
|
||||
@@ -46,19 +46,65 @@ QGIHighlight::QGIHighlight()
|
||||
{
|
||||
m_refText = "";
|
||||
m_refSize = 0.0;
|
||||
setInteractive(false);
|
||||
|
||||
m_circle = new QGraphicsEllipseItem();
|
||||
addToGroup(m_circle);
|
||||
m_circle->setFlag(QGraphicsItem::ItemIsSelectable, false);
|
||||
|
||||
m_rect = new QGCustomRect();
|
||||
addToGroup(m_rect);
|
||||
m_rect->setFlag(QGraphicsItem::ItemIsSelectable, false);
|
||||
|
||||
m_reference = new QGCustomText();
|
||||
addToGroup(m_reference);
|
||||
m_reference->setFlag(QGraphicsItem::ItemIsSelectable, false);
|
||||
|
||||
setWidth(Rez::guiX(0.75));
|
||||
setStyle(getHighlightStyle());
|
||||
setColor(getHighlightColor());
|
||||
}
|
||||
|
||||
QGIHighlight::~QGIHighlight()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//really only want to emit signal at end of movement
|
||||
//QVariant QGIHighlight::itemChange(GraphicsItemChange change, const QVariant &value)
|
||||
//{
|
||||
// if (change == ItemPositionHasChanged && scene()) {
|
||||
// // nothing to do here
|
||||
// }
|
||||
// return QGraphicsItem::itemChange(change, value);
|
||||
//}
|
||||
|
||||
//void QGIHighlight::mousePressEvent(QGraphicsSceneMouseEvent * event)
|
||||
//{
|
||||
// Base::Console().Message("QGIHighlight::mousePress() - %X\n", this);
|
||||
//// if(scene() && m_reference == scene()->mouseGrabberItem()) {
|
||||
// if ( (event->button() == Qt::LeftButton) &&
|
||||
// (flags() && QGraphicsItem::ItemIsMovable) ) {
|
||||
// m_dragging = true;
|
||||
// }
|
||||
//// }
|
||||
// QGIDecoration::mousePressEvent(event);
|
||||
//}
|
||||
|
||||
//void QGIHighlight::mouseReleaseEvent(QGraphicsSceneMouseEvent * event)
|
||||
//{
|
||||
// Base::Console().Message("QGIHighlight::mouseRelease() - %X grabber: %X\n", this, scene()->mouseGrabberItem());
|
||||
//// if(scene() && this == scene()->mouseGrabberItem()) {
|
||||
// if (m_dragging) {
|
||||
// m_dragging = false;
|
||||
//// QString itemName = data(0).toString();
|
||||
// Q_EMIT positionChange(pos());
|
||||
// return;
|
||||
// }
|
||||
//// }
|
||||
// QGIDecoration::mouseReleaseEvent(event);
|
||||
//}
|
||||
|
||||
void QGIHighlight::draw()
|
||||
{
|
||||
prepareGeometryChange();
|
||||
@@ -100,6 +146,15 @@ void QGIHighlight::makeReference()
|
||||
}
|
||||
}
|
||||
|
||||
void QGIHighlight::setInteractive(bool state)
|
||||
{
|
||||
// setAcceptHoverEvents(state);
|
||||
setFlag(QGraphicsItem::ItemIsSelectable, state);
|
||||
setFlag(QGraphicsItem::ItemIsMovable, state);
|
||||
setFlag(QGraphicsItem::ItemSendsScenePositionChanges, state);
|
||||
setFlag(QGraphicsItem::ItemSendsGeometryChanges, state);
|
||||
}
|
||||
|
||||
void QGIHighlight::setBounds(double x1,double y1,double x2,double y2)
|
||||
{
|
||||
m_start = QPointF(Rez::guiX(x1),Rez::guiX(-y1));
|
||||
@@ -142,10 +197,9 @@ int QGIHighlight::getHoleStyle()
|
||||
return style;
|
||||
}
|
||||
|
||||
|
||||
void QGIHighlight::paint ( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget) {
|
||||
QStyleOptionGraphicsItem myOption(*option);
|
||||
myOption.state &= ~QStyle::State_Selected;
|
||||
// myOption.state &= ~QStyle::State_Selected;
|
||||
|
||||
setTools();
|
||||
// painter->drawRect(boundingRect()); //good for debugging
|
||||
@@ -165,3 +219,4 @@ void QGIHighlight::setTools()
|
||||
|
||||
m_reference->setDefaultTextColor(m_colCurrent);
|
||||
}
|
||||
|
||||
|
||||
@@ -25,9 +25,12 @@
|
||||
|
||||
#include <QFont>
|
||||
#include <QPointF>
|
||||
#include <QObject>
|
||||
#include <QGraphicsTextItem>
|
||||
#include <QGraphicsRectItem>
|
||||
#include <QGraphicsEllipseItem>
|
||||
#include <QGraphicsScene>
|
||||
#include <QGraphicsSceneEvent>
|
||||
#include <QPainterPath>
|
||||
#include <QColor>
|
||||
|
||||
@@ -45,19 +48,25 @@ class TechDrawGuiExport QGIHighlight : public QGIDecoration
|
||||
{
|
||||
public:
|
||||
explicit QGIHighlight();
|
||||
~QGIHighlight() {}
|
||||
~QGIHighlight();
|
||||
|
||||
enum {Type = QGraphicsItem::UserType + 172};
|
||||
enum {Type = QGraphicsItem::UserType + 176};
|
||||
int type() const { return Type;}
|
||||
|
||||
virtual void paint(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget = 0 );
|
||||
virtual void paint(QPainter * painter,
|
||||
const QStyleOptionGraphicsItem * option,
|
||||
QWidget * widget = 0 ) override;
|
||||
|
||||
void setBounds(double x1,double y1,double x2,double y2);
|
||||
void setReference(char* sym);
|
||||
void setFont(QFont f, double fsize);
|
||||
virtual void draw();
|
||||
void setInteractive(bool state);
|
||||
|
||||
protected:
|
||||
/* virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value) override;*/
|
||||
/* virtual void mousePressEvent(QGraphicsSceneMouseEvent *event) override;*/
|
||||
/* virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;*/
|
||||
QColor getHighlightColor();
|
||||
Qt::PenStyle getHighlightStyle();
|
||||
void makeHighlight();
|
||||
@@ -65,6 +74,7 @@ protected:
|
||||
void setTools();
|
||||
int getHoleStyle(void);
|
||||
|
||||
/* bool m_dragging;*/
|
||||
|
||||
private:
|
||||
char* m_refText;
|
||||
|
||||
@@ -1,26 +1,26 @@
|
||||
/*
|
||||
Derived QGraphicsItem Classes type() Values
|
||||
Derived QGI Classes type() Values
|
||||
|
||||
Qt First UserType>> QGraphicsItem::UserType = 65536
|
||||
|
||||
QGraphicsItemView : 101
|
||||
QGraphicsItemViewPart : 102
|
||||
QGraphicsItemEdge: 103
|
||||
QGraphicsItemFace: 104
|
||||
QGraphicsItemVertex: 105
|
||||
QGraphicsItemViewDimension : 106
|
||||
QGraphicsItemViewBalloon : 140
|
||||
QGraphicsItemBalloonLabel : 141
|
||||
QGraphicsItemDatumLabel : 107
|
||||
QGraphicsItemViewSection : 108
|
||||
QGraphicsItemArrow: 109
|
||||
QGraphicsItemViewCollection : 110
|
||||
QGraphicsItemViewOrthographic : 113
|
||||
QGraphicsItemViewAnnotation : 120
|
||||
QGraphicsItemViewSymbol : 121
|
||||
QGraphicsItemHatch : 122 //obsolete
|
||||
QGraphicsItemClip : 123
|
||||
QGraphicsItemSpreadsheet : 124
|
||||
QGIView : 101
|
||||
QGIViewPart : 102
|
||||
QGIEdge: 103
|
||||
QGIFace: 104
|
||||
QGIVertex: 105
|
||||
QGIViewDimension : 106
|
||||
QGIViewBalloon : 140
|
||||
QGIBalloonLabel : 141
|
||||
QGIDatumLabel : 107
|
||||
QGIViewSection : 108
|
||||
QGIArrow: 109
|
||||
QGIViewCollection : 110
|
||||
QGIProjGroup : 113
|
||||
QGIViewAnnotation : 120
|
||||
QGIViewSymbol : 121
|
||||
QGIHatch : 122 //obsolete
|
||||
QGIClip : 123
|
||||
QGISpreadsheet : 124
|
||||
QGCustomText: 130
|
||||
QGCustomSvg: 131
|
||||
QGCustomClip: 132
|
||||
@@ -28,9 +28,9 @@ QGCustomRect: 133
|
||||
QGCustomLabel:135
|
||||
QGCustomBorder: 136
|
||||
QGDisplayArea: 137
|
||||
QGraphicsItemTemplate: 150
|
||||
QGraphicsItemDrawingTemplate: 151
|
||||
QGraphicsItemSVGTemplate: 153
|
||||
QGITemplate: 150
|
||||
QGIDrawingTemplate: 151
|
||||
QGISVGTemplate: 153
|
||||
TemplateTextField: 160
|
||||
QGIPrimPath: 170
|
||||
QGICMark: 171
|
||||
@@ -38,6 +38,8 @@ QGISectionLine: 172
|
||||
QGIDecoration: 173
|
||||
QGICenterLine: 174
|
||||
QGIDimLines: 175
|
||||
QGIHighlight: 176
|
||||
QGIGhostHighlight: 177
|
||||
QGICaption: 180
|
||||
QGIViewImage: 200
|
||||
QGCustomImage: 201
|
||||
|
||||
@@ -121,6 +121,11 @@ public:
|
||||
static int calculateFontPixelWidth(const QFont &font);
|
||||
static const double DefaultFontSizeInMM;
|
||||
|
||||
static QString getPrefFont(void);
|
||||
static double getPrefFontSize(void);
|
||||
static double getDimFontSize(void);
|
||||
|
||||
|
||||
MDIViewPage* getMDIViewPage(void) const;
|
||||
virtual void removeChild(QGIView* child);
|
||||
|
||||
@@ -145,9 +150,9 @@ protected:
|
||||
virtual QRectF customChildrenBoundingRect(void) const;
|
||||
void dumpRect(const char* text, QRectF r);
|
||||
|
||||
QString getPrefFont(void);
|
||||
double getPrefFontSize(void);
|
||||
double getDimFontSize(void);
|
||||
/* QString getPrefFont(void);*/
|
||||
/* double getPrefFontSize(void);*/
|
||||
/* double getDimFontSize(void);*/
|
||||
|
||||
Base::Reference<ParameterGrp> getParmGroupCol(void);
|
||||
|
||||
|
||||
@@ -67,6 +67,11 @@ Base::Vector2d Rez::guiX(Base::Vector3d v, bool planar)
|
||||
return Base::Vector2d(guiX(v.x), guiX(v.y));
|
||||
}
|
||||
|
||||
QPointF Rez::guiX(QPointF p)
|
||||
{
|
||||
return Rez::guiPt(p);
|
||||
}
|
||||
|
||||
//turn Gui side value to App side value
|
||||
double Rez::appX(double x)
|
||||
{
|
||||
@@ -85,6 +90,7 @@ QPointF Rez::appX(QPointF p)
|
||||
}
|
||||
|
||||
|
||||
|
||||
//Misc conversions
|
||||
QPointF Rez::guiPt(QPointF p)
|
||||
{
|
||||
|
||||
@@ -43,6 +43,8 @@ public:
|
||||
static double guiX(double x);
|
||||
static Base::Vector3d guiX(Base::Vector3d v);
|
||||
static Base::Vector2d guiX(Base::Vector3d v, bool planar);
|
||||
static QPointF guiX(QPointF p);
|
||||
|
||||
//turn Gui side value to App side value
|
||||
static double appX(double x);
|
||||
static Base::Vector3d appX(Base::Vector3d v);
|
||||
|
||||
@@ -0,0 +1,585 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2020 Wandererfan <wandererfan@gmail.com *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#ifndef _PreComp_
|
||||
#include <QGraphicsScene>
|
||||
#include <QStatusBar>
|
||||
#endif // #ifndef _PreComp_
|
||||
|
||||
#include <Base/Console.h>
|
||||
#include <Base/Tools.h>
|
||||
#include <Base/Quantity.h>
|
||||
#include <Base/UnitsApi.h>
|
||||
|
||||
#include <Gui/Application.h>
|
||||
#include <Gui/BitmapFactory.h>
|
||||
#include <Gui/Command.h>
|
||||
#include <Gui/Control.h>
|
||||
#include <Gui/Document.h>
|
||||
#include <Gui/MainWindow.h>
|
||||
#include <Gui/Selection.h>
|
||||
#include <Gui/ViewProvider.h>
|
||||
#include <Gui/WaitCursor.h>
|
||||
|
||||
#include <Mod/TechDraw/App/DrawPage.h>
|
||||
#include <Mod/TechDraw/App/DrawUtil.h>
|
||||
#include <Mod/TechDraw/App/DrawView.h>
|
||||
#include <Mod/TechDraw/App/DrawViewPart.h>
|
||||
#include <Mod/TechDraw/App/DrawViewDetail.h>
|
||||
|
||||
#include <Mod/TechDraw/Gui/ui_TaskDetail.h>
|
||||
|
||||
#include "DrawGuiStd.h"
|
||||
#include "QGVPage.h"
|
||||
#include "QGIView.h"
|
||||
#include "QGIPrimPath.h"
|
||||
#include "QGIGhostHighlight.h"
|
||||
#include "MDIViewPage.h"
|
||||
#include "ViewProviderPage.h"
|
||||
#include "Rez.h"
|
||||
#include "QGIViewPart.h"
|
||||
|
||||
#include "TaskDetail.h"
|
||||
|
||||
using namespace TechDrawGui;
|
||||
using namespace TechDraw;
|
||||
using namespace Gui;
|
||||
|
||||
#define CREATEMODE 0
|
||||
#define EDITMODE 1
|
||||
|
||||
//creation ctor
|
||||
TaskDetail::TaskDetail(TechDraw::DrawViewPart* baseFeat):
|
||||
ui(new Ui_TaskDetail),
|
||||
m_detailFeat(nullptr),
|
||||
m_baseFeat(baseFeat),
|
||||
m_basePage(nullptr),
|
||||
m_inProgressLock(false),
|
||||
m_saveAnchor(Base::Vector3d(0.0, 0.0, 0.0)),
|
||||
m_saveRadius(0.0),
|
||||
m_baseName(std::string()),
|
||||
m_pageName(std::string()),
|
||||
m_detailName(std::string()),
|
||||
m_doc(nullptr),
|
||||
m_mode(CREATEMODE),
|
||||
m_created(false)
|
||||
{
|
||||
if (m_baseFeat == nullptr) {
|
||||
//should be caught in CMD caller
|
||||
Base::Console().Error("TaskDetail - bad parameters - base feature. Can not proceed.\n");
|
||||
return;
|
||||
}
|
||||
m_basePage = m_baseFeat->findParentPage();
|
||||
if (m_basePage == nullptr) {
|
||||
Base::Console().Error("TaskDetail - bad parameters - base page. Can not proceed.\n");
|
||||
}
|
||||
|
||||
m_baseName = m_baseFeat->getNameInDocument();
|
||||
m_doc = m_baseFeat->getDocument();
|
||||
m_pageName = m_basePage->getNameInDocument();
|
||||
|
||||
ui->setupUi(this);
|
||||
|
||||
Gui::Document* activeGui = Gui::Application::Instance->getDocument(m_doc);
|
||||
Gui::ViewProvider* vp = activeGui->getViewProvider(m_basePage);
|
||||
ViewProviderPage* vpp = static_cast<ViewProviderPage*>(vp);
|
||||
m_mdi = vpp->getMDIViewPage();
|
||||
m_scene = m_mdi->m_scene;
|
||||
m_view = m_mdi->getQGVPage();
|
||||
|
||||
createDetail();
|
||||
setUiFromFeat();
|
||||
setWindowTitle(QObject::tr("New Detail"));
|
||||
|
||||
connect(ui->pbDragger, SIGNAL(clicked(bool)),
|
||||
this, SLOT(onDraggerClicked(bool)));
|
||||
connect(ui->qsbX, SIGNAL(editingFinished()),
|
||||
this, SLOT(onXEdit()));
|
||||
connect(ui->qsbY, SIGNAL(editingFinished()),
|
||||
this, SLOT(onYEdit()));
|
||||
connect(ui->qsbRadius, SIGNAL(editingFinished()),
|
||||
this, SLOT(onRadiusEdit()));
|
||||
|
||||
m_ghost = new QGIGhostHighlight();
|
||||
m_scene->addItem(m_ghost);
|
||||
m_ghost->hide();
|
||||
connect(m_ghost, SIGNAL(positionChange(QPointF)),
|
||||
this, SLOT(onHighlightMoved(QPointF)));
|
||||
}
|
||||
|
||||
//edit ctor
|
||||
TaskDetail::TaskDetail(TechDraw::DrawViewDetail* detailFeat):
|
||||
ui(new Ui_TaskDetail),
|
||||
m_detailFeat(detailFeat),
|
||||
m_baseFeat(nullptr),
|
||||
m_basePage(nullptr),
|
||||
m_inProgressLock(false),
|
||||
m_saveAnchor(Base::Vector3d(0.0, 0.0, 0.0)),
|
||||
m_saveRadius(0.0),
|
||||
m_baseName(std::string()),
|
||||
m_pageName(std::string()),
|
||||
m_detailName(std::string()),
|
||||
m_doc(nullptr),
|
||||
m_mode(EDITMODE),
|
||||
m_created(false)
|
||||
{
|
||||
if (m_detailFeat == nullptr) {
|
||||
//should be caught in CMD caller
|
||||
Base::Console().Error("TaskDetail - bad parameters. Can not proceed.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
m_doc = m_detailFeat->getDocument();
|
||||
m_detailName = m_detailFeat->getNameInDocument();
|
||||
|
||||
m_basePage = m_detailFeat->findParentPage();
|
||||
if (m_basePage != nullptr) {
|
||||
m_pageName = m_basePage->getNameInDocument();
|
||||
}
|
||||
|
||||
App::DocumentObject* baseObj = m_detailFeat->BaseView.getValue();
|
||||
m_baseFeat = dynamic_cast<TechDraw::DrawViewPart*>(baseObj);
|
||||
if (m_baseFeat != nullptr) {
|
||||
m_baseName = m_baseFeat->getNameInDocument();
|
||||
} else {
|
||||
Base::Console().Error("TaskDetail - no BaseView. Can not proceed.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ui->setupUi(this);
|
||||
|
||||
Gui::Document* activeGui = Gui::Application::Instance->getDocument(m_basePage->getDocument());
|
||||
Gui::ViewProvider* vp = activeGui->getViewProvider(m_basePage);
|
||||
ViewProviderPage* vpp = static_cast<ViewProviderPage*>(vp);
|
||||
m_mdi = vpp->getMDIViewPage();
|
||||
m_scene = m_mdi->m_scene;
|
||||
m_view = m_mdi->getQGVPage();
|
||||
|
||||
saveDetailState();
|
||||
setUiFromFeat();
|
||||
setWindowTitle(QObject::tr("Edit Detail"));
|
||||
|
||||
connect(ui->pbDragger, SIGNAL(clicked(bool)),
|
||||
this, SLOT(onDraggerClicked(bool)));
|
||||
connect(ui->qsbX, SIGNAL(editingFinished()),
|
||||
this, SLOT(onXEdit()));
|
||||
connect(ui->qsbY, SIGNAL(editingFinished()),
|
||||
this, SLOT(onYEdit()));
|
||||
connect(ui->qsbRadius, SIGNAL(editingFinished()),
|
||||
this, SLOT(onRadiusEdit()));
|
||||
connect(ui->aeReference, SIGNAL(editingFinished()),
|
||||
this, SLOT(onReferenceEdit()));
|
||||
|
||||
m_ghost = new QGIGhostHighlight();
|
||||
m_scene->addItem(m_ghost);
|
||||
m_ghost->hide();
|
||||
connect(m_ghost, SIGNAL(positionChange(QPointF)),
|
||||
this, SLOT(onHighlightMoved(QPointF)));
|
||||
}
|
||||
|
||||
TaskDetail::~TaskDetail()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void TaskDetail::updateTask()
|
||||
{
|
||||
// blockUpdate = true;
|
||||
|
||||
// blockUpdate = false;
|
||||
}
|
||||
|
||||
void TaskDetail::changeEvent(QEvent *e)
|
||||
{
|
||||
if (e->type() == QEvent::LanguageChange) {
|
||||
ui->retranslateUi(this);
|
||||
}
|
||||
}
|
||||
|
||||
//save the start conditions
|
||||
void TaskDetail::saveDetailState()
|
||||
{
|
||||
// Base::Console().Message("TD::saveDetailState()\n");
|
||||
TechDraw::DrawViewDetail* dvd = getDetailFeat();
|
||||
m_saveAnchor = dvd->AnchorPoint.getValue();
|
||||
m_saveRadius = dvd->Radius.getValue();
|
||||
m_saved = true;
|
||||
}
|
||||
|
||||
void TaskDetail::restoreDetailState()
|
||||
{
|
||||
// Base::Console().Message("TD::restoreDetailState()\n");
|
||||
TechDraw::DrawViewDetail* dvd = getDetailFeat();
|
||||
dvd->AnchorPoint.setValue(m_saveAnchor);
|
||||
dvd->Radius.setValue(m_saveRadius);
|
||||
}
|
||||
|
||||
//***** ui stuff ***************************************************************
|
||||
|
||||
void TaskDetail::setUiFromFeat()
|
||||
{
|
||||
// Base::Console().Message("TD::setUIFromFeat()\n");
|
||||
if (m_baseFeat != nullptr) {
|
||||
std::string baseName = getBaseFeat()->getNameInDocument();
|
||||
ui->leBaseView->setText(Base::Tools::fromStdString(baseName));
|
||||
}
|
||||
|
||||
Base::Vector3d anchor;
|
||||
double radius;
|
||||
|
||||
TechDraw::DrawViewDetail* detailFeat = getDetailFeat();
|
||||
QString detailDisplay = QString::fromUtf8(detailFeat->getNameInDocument()) +
|
||||
QString::fromUtf8(" / ") +
|
||||
QString::fromUtf8(detailFeat->Label.getValue());
|
||||
ui->leDetailView->setText(detailDisplay);
|
||||
anchor = detailFeat->AnchorPoint.getValue();
|
||||
radius = detailFeat->Radius.getValue();
|
||||
QString ref = QString::fromUtf8(detailFeat->Reference.getValue());
|
||||
|
||||
ui->pbDragger->setText(QString::fromUtf8("Drag Highlight"));
|
||||
ui->pbDragger->setEnabled(true);
|
||||
int decimals = Base::UnitsApi::getDecimals();
|
||||
ui->qsbX->setUnit(Base::Unit::Length);
|
||||
ui->qsbX->setDecimals(decimals);
|
||||
ui->qsbY->setUnit(Base::Unit::Length);
|
||||
ui->qsbY->setDecimals(decimals);
|
||||
ui->qsbRadius->setDecimals(decimals);
|
||||
ui->qsbRadius->setUnit(Base::Unit::Length);
|
||||
ui->qsbX->setValue(anchor.x);
|
||||
ui->qsbY->setValue(anchor.y);
|
||||
ui->qsbRadius->setValue(radius);
|
||||
ui->aeReference->setText(ref);
|
||||
}
|
||||
|
||||
//update ui point fields after tracker finishes
|
||||
void TaskDetail::updateUi(QPointF p)
|
||||
{
|
||||
ui->qsbX->setValue(p.x());
|
||||
ui->qsbY->setValue(- p.y());
|
||||
}
|
||||
|
||||
void TaskDetail::enableInputFields(bool b)
|
||||
{
|
||||
ui->qsbX->setEnabled(b);
|
||||
ui->qsbY->setEnabled(b);
|
||||
ui->qsbRadius->setEnabled(b);
|
||||
ui->aeReference->setEnabled(b);
|
||||
}
|
||||
|
||||
void TaskDetail::onXEdit()
|
||||
{
|
||||
updateDetail();
|
||||
}
|
||||
|
||||
void TaskDetail::onYEdit()
|
||||
{
|
||||
updateDetail();
|
||||
}
|
||||
|
||||
void TaskDetail::onRadiusEdit()
|
||||
{
|
||||
updateDetail();
|
||||
}
|
||||
|
||||
void TaskDetail::onReferenceEdit()
|
||||
{
|
||||
updateDetail();
|
||||
}
|
||||
|
||||
void TaskDetail::onDraggerClicked(bool b)
|
||||
{
|
||||
Q_UNUSED(b);
|
||||
ui->pbDragger->setEnabled(false);
|
||||
enableInputFields(false);
|
||||
editByHighlight();
|
||||
return;
|
||||
}
|
||||
|
||||
void TaskDetail::editByHighlight()
|
||||
{
|
||||
// Base::Console().Message("TD::editByHighlight()\n");
|
||||
if (m_ghost == nullptr) {
|
||||
Base::Console().Error("TaskDetail::editByHighlight - no ghost object\n");
|
||||
return;
|
||||
}
|
||||
|
||||
m_scene->clearSelection();
|
||||
m_ghost->setSelected(true);
|
||||
m_ghost->setPos(getAnchorScene());
|
||||
m_ghost->draw();
|
||||
m_ghost->show();
|
||||
}
|
||||
|
||||
//dragEnd is in scene coords.
|
||||
void TaskDetail::onHighlightMoved(QPointF dragEnd)
|
||||
{
|
||||
// Base::Console().Message("TD::onHighlightMoved(%s) - highlight: %X\n",
|
||||
// DrawUtil::formatVector(dragEnd).c_str(), m_ghost);
|
||||
ui->pbDragger->setEnabled(true);
|
||||
|
||||
double scale = getBaseFeat()->getScale();
|
||||
double x = Rez::guiX(getBaseFeat()->X.getValue()) * scale;
|
||||
double y = Rez::guiX(getBaseFeat()->Y.getValue()) * scale;
|
||||
QPointF basePosScene(x, -y); //base position in scene coords
|
||||
|
||||
QPointF anchorDisplace = dragEnd - basePosScene;
|
||||
QPointF newAnchorPos = Rez::appX(anchorDisplace) / scale;
|
||||
|
||||
updateUi(newAnchorPos);
|
||||
updateDetail();
|
||||
enableInputFields(true);
|
||||
m_ghost->setSelected(false);
|
||||
m_ghost->hide();
|
||||
}
|
||||
|
||||
void TaskDetail::saveButtons(QPushButton* btnOK,
|
||||
QPushButton* btnCancel)
|
||||
{
|
||||
m_btnOK = btnOK;
|
||||
m_btnCancel = btnCancel;
|
||||
}
|
||||
|
||||
void TaskDetail::enableTaskButtons(bool b)
|
||||
{
|
||||
m_btnOK->setEnabled(b);
|
||||
m_btnCancel->setEnabled(b);
|
||||
}
|
||||
|
||||
//***** Feature create & edit stuff *******************************************
|
||||
void TaskDetail::createDetail()
|
||||
{
|
||||
// Base::Console().Message("TD::createDetail()\n");
|
||||
Gui::Command::openCommand("Create Detail");
|
||||
|
||||
m_detailName = m_doc->getUniqueObjectName("Detail");
|
||||
|
||||
Gui::Command::doCommand(Command::Doc,"App.activeDocument().addObject('TechDraw::DrawViewDetail','%s')",
|
||||
m_detailName.c_str());
|
||||
App::DocumentObject *docObj = m_doc->getObject(m_detailName.c_str());
|
||||
TechDraw::DrawViewDetail* dvd = dynamic_cast<TechDraw::DrawViewDetail *>(docObj);
|
||||
if (!dvd) {
|
||||
throw Base::TypeError("TaskDetail - new detail not found\n");
|
||||
}
|
||||
m_detailFeat = dvd;
|
||||
|
||||
dvd->Source.setValues(getBaseFeat()->Source.getValues());
|
||||
|
||||
Gui::Command::doCommand(Command::Doc,"App.activeDocument().%s.BaseView = App.activeDocument().%s",
|
||||
m_detailName.c_str(),m_baseName.c_str());
|
||||
Gui::Command::doCommand(Command::Doc,"App.activeDocument().%s.Direction = App.activeDocument().%s.Direction",
|
||||
m_detailName.c_str(),m_baseName.c_str());
|
||||
Gui::Command::doCommand(Command::Doc,"App.activeDocument().%s.XDirection = App.activeDocument().%s.XDirection",
|
||||
m_detailName.c_str(),m_baseName.c_str());
|
||||
Gui::Command::doCommand(Command::Doc,"App.activeDocument().%s.addView(App.activeDocument().%s)",
|
||||
m_pageName.c_str(), m_detailName.c_str());
|
||||
|
||||
Gui::Command::updateActive();
|
||||
Gui::Command::commitCommand();
|
||||
|
||||
getBaseFeat()->requestPaint();
|
||||
m_created = true;
|
||||
}
|
||||
|
||||
void TaskDetail::updateDetail()
|
||||
{
|
||||
// Base::Console().Message("TD::updateDetail()\n");
|
||||
Gui::Command::openCommand("Update Detail");
|
||||
double x = ui->qsbX->rawValue();
|
||||
double y = ui->qsbY->rawValue();
|
||||
Base::Vector3d temp(x, y, 0.0);
|
||||
TechDraw::DrawViewDetail* detailFeat = getDetailFeat();
|
||||
detailFeat->AnchorPoint.setValue(temp);
|
||||
|
||||
double radius = ui->qsbRadius->rawValue();
|
||||
detailFeat->Radius.setValue(radius);
|
||||
QString qRef = ui->aeReference->text();
|
||||
std::string ref = Base::Tools::toStdString(qRef);
|
||||
detailFeat->Reference.setValue(ref);
|
||||
|
||||
detailFeat->recomputeFeature();
|
||||
getBaseFeat()->requestPaint();
|
||||
Gui::Command::updateActive();
|
||||
Gui::Command::commitCommand();
|
||||
}
|
||||
|
||||
//***** Getters ****************************************************************
|
||||
|
||||
//get the current Anchor highlight position in scene coords
|
||||
QPointF TaskDetail::getAnchorScene()
|
||||
{
|
||||
TechDraw::DrawViewPart* dvp = getBaseFeat();
|
||||
TechDraw::DrawViewDetail* dvd = getDetailFeat();
|
||||
|
||||
Base::Vector3d anchorPos = dvd->AnchorPoint.getValue();
|
||||
double x = dvp->X.getValue();
|
||||
double y = dvp->Y.getValue();
|
||||
Base::Vector3d basePos(x, y, 0.0);
|
||||
Base::Vector3d netPos = basePos + anchorPos;
|
||||
netPos = Rez::guiX(netPos * dvp->getScale());
|
||||
|
||||
QPointF qAnchor(netPos.x, - netPos.y);
|
||||
return qAnchor;
|
||||
}
|
||||
|
||||
// protects against stale pointers
|
||||
DrawViewPart* TaskDetail::getBaseFeat()
|
||||
{
|
||||
// Base::Console().Message("TD::getBaseFeat()\n");
|
||||
DrawViewPart* result = nullptr;
|
||||
|
||||
if (m_doc != nullptr) {
|
||||
App::DocumentObject* baseObj = m_doc->getObject(m_baseName.c_str());
|
||||
if (baseObj != nullptr) {
|
||||
result = static_cast<DrawViewPart*>(baseObj);
|
||||
}
|
||||
}
|
||||
if (result == nullptr) {
|
||||
std::string msg = "TaskDetail - base feature " +
|
||||
m_baseName +
|
||||
" not found \n";
|
||||
throw Base::TypeError(msg);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// protects against stale pointers
|
||||
DrawViewDetail* TaskDetail::getDetailFeat()
|
||||
{
|
||||
// Base::Console().Message("TD::getDetailFeat()\n");
|
||||
DrawViewDetail* result = nullptr;
|
||||
|
||||
if (m_doc != nullptr) {
|
||||
App::DocumentObject* detailObj = m_doc->getObject(m_detailName.c_str());
|
||||
if (detailObj != nullptr) {
|
||||
result = static_cast<DrawViewDetail*>(detailObj);
|
||||
}
|
||||
}
|
||||
if (result == nullptr) {
|
||||
std::string msg = "TaskDetail - detail feature " +
|
||||
m_detailName +
|
||||
" not found \n";
|
||||
// throw Base::TypeError("TaskDetail - detail feature not found\n");
|
||||
throw Base::TypeError(msg);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
|
||||
bool TaskDetail::accept()
|
||||
{
|
||||
// Base::Console().Message("TD::accept()\n");
|
||||
|
||||
Gui::Document* doc = Gui::Application::Instance->getDocument(m_basePage->getDocument());
|
||||
if (!doc) return false;
|
||||
|
||||
getDetailFeat()->requestPaint();
|
||||
getBaseFeat()->requestPaint();
|
||||
Gui::Command::doCommand(Gui::Command::Gui,"Gui.ActiveDocument.resetEdit()");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TaskDetail::reject()
|
||||
{
|
||||
// Base::Console().Message("TD::reject()\n");
|
||||
Gui::Document* doc = Gui::Application::Instance->getDocument(m_basePage->getDocument());
|
||||
if (!doc) return false;
|
||||
|
||||
if (m_mode == CREATEMODE) {
|
||||
if (m_created) {
|
||||
Gui::Command::doCommand(Gui::Command::Gui,"App.activeDocument().removeObject('%s')",
|
||||
m_detailName.c_str());
|
||||
}
|
||||
} else {
|
||||
restoreDetailState();
|
||||
getDetailFeat()->recomputeFeature();
|
||||
getBaseFeat()->requestPaint();
|
||||
}
|
||||
|
||||
Gui::Command::doCommand(Gui::Command::Gui,"App.activeDocument().recompute()");
|
||||
Gui::Command::doCommand(Gui::Command::Gui,"Gui.ActiveDocument.resetEdit()");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
TaskDlgDetail::TaskDlgDetail(TechDraw::DrawViewPart* baseFeat)
|
||||
: TaskDialog()
|
||||
{
|
||||
widget = new TaskDetail(baseFeat);
|
||||
taskbox = new Gui::TaskView::TaskBox(Gui::BitmapFactory().pixmap("actions/techdraw-DetailView"),
|
||||
widget->windowTitle(), true, 0);
|
||||
taskbox->groupLayout()->addWidget(widget);
|
||||
Content.push_back(taskbox);
|
||||
}
|
||||
|
||||
TaskDlgDetail::TaskDlgDetail(TechDraw::DrawViewDetail* detailFeat)
|
||||
: TaskDialog()
|
||||
{
|
||||
widget = new TaskDetail(detailFeat);
|
||||
taskbox = new Gui::TaskView::TaskBox(Gui::BitmapFactory().pixmap("actions/techdraw-DetailView"),
|
||||
widget->windowTitle(), true, 0);
|
||||
taskbox->groupLayout()->addWidget(widget);
|
||||
Content.push_back(taskbox);
|
||||
}
|
||||
|
||||
TaskDlgDetail::~TaskDlgDetail()
|
||||
{
|
||||
}
|
||||
|
||||
void TaskDlgDetail::update()
|
||||
{
|
||||
// widget->updateTask();
|
||||
}
|
||||
|
||||
void TaskDlgDetail::modifyStandardButtons(QDialogButtonBox* box)
|
||||
{
|
||||
QPushButton* btnOK = box->button(QDialogButtonBox::Ok);
|
||||
QPushButton* btnCancel = box->button(QDialogButtonBox::Cancel);
|
||||
widget->saveButtons(btnOK, btnCancel);
|
||||
}
|
||||
|
||||
//==== calls from the TaskView ===============================================================
|
||||
void TaskDlgDetail::open()
|
||||
{
|
||||
}
|
||||
|
||||
void TaskDlgDetail::clicked(int)
|
||||
{
|
||||
}
|
||||
|
||||
bool TaskDlgDetail::accept()
|
||||
{
|
||||
widget->accept();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TaskDlgDetail::reject()
|
||||
{
|
||||
widget->reject();
|
||||
return true;
|
||||
}
|
||||
|
||||
#include <Mod/TechDraw/Gui/moc_TaskDetail.cpp>
|
||||
@@ -0,0 +1,179 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2020 WandererFan <wandererfan@gmail.com> *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef TECHDRAWGUI_TASKCOSVERTEX_H
|
||||
#define TECHDRAWGUI_TASKCOSVERTEX_H
|
||||
|
||||
#include <App/DocumentObject.h>
|
||||
#include <Base/Vector3D.h>
|
||||
#include <Gui/TaskView/TaskView.h>
|
||||
#include <Gui/TaskView/TaskDialog.h>
|
||||
|
||||
#include <Mod/TechDraw/Gui/ui_TaskDetail.h>
|
||||
|
||||
//TODO: make this a proper enum
|
||||
#define TRACKERPICK 0
|
||||
#define TRACKEREDIT 1
|
||||
#define TRACKERCANCEL 2
|
||||
#define TRACKERCANCELEDIT 3
|
||||
|
||||
class Ui_TaskDetail;
|
||||
|
||||
namespace App {
|
||||
class DocumentObject;
|
||||
}
|
||||
|
||||
namespace TechDraw
|
||||
{
|
||||
class DrawPage;
|
||||
class DrawView;
|
||||
class DrawDetail;
|
||||
class DrawViewPart;
|
||||
}
|
||||
|
||||
namespace TechDrawGui
|
||||
{
|
||||
class QGVPage;
|
||||
class QGIView;
|
||||
class QGIPrimPath;
|
||||
class MDIViewPage;
|
||||
class QGEPath;
|
||||
class QGIDetail;
|
||||
class QGIGhostHighlight;
|
||||
class ViewProviderLeader;
|
||||
|
||||
class TaskDetail : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
TaskDetail(TechDraw::DrawViewPart* baseFeat);
|
||||
TaskDetail(TechDraw::DrawViewDetail* detailFeat);
|
||||
~TaskDetail();
|
||||
|
||||
public Q_SLOTS:
|
||||
void onDraggerClicked(bool b);
|
||||
void onHighlightMoved(QPointF newPos);
|
||||
void onXEdit();
|
||||
void onYEdit();
|
||||
void onRadiusEdit();
|
||||
void onReferenceEdit();
|
||||
|
||||
public:
|
||||
virtual bool accept();
|
||||
virtual bool reject();
|
||||
void updateTask();
|
||||
void saveButtons(QPushButton* btnOK,
|
||||
QPushButton* btnCancel);
|
||||
void enableTaskButtons(bool b);
|
||||
|
||||
protected:
|
||||
void changeEvent(QEvent *e);
|
||||
void startDragger(void);
|
||||
|
||||
void createDetail();
|
||||
void updateDetail();
|
||||
|
||||
void editByHighlight();
|
||||
|
||||
void blockButtons(bool b);
|
||||
void setUiFromFeat(void);
|
||||
void updateUi(QPointF p);
|
||||
void enableInputFields(bool b);
|
||||
|
||||
void saveDetailState();
|
||||
void restoreDetailState();
|
||||
QPointF getAnchorScene();
|
||||
|
||||
TechDraw::DrawViewPart* getBaseFeat();
|
||||
TechDraw::DrawViewDetail* getDetailFeat();
|
||||
|
||||
private:
|
||||
Ui_TaskDetail * ui;
|
||||
bool blockUpdate;
|
||||
|
||||
QGIGhostHighlight* m_ghost;
|
||||
|
||||
MDIViewPage* m_mdi;
|
||||
QGraphicsScene* m_scene;
|
||||
QGVPage* m_view;
|
||||
TechDraw::DrawViewDetail* m_detailFeat;
|
||||
TechDraw::DrawViewPart* m_baseFeat;
|
||||
TechDraw::DrawPage* m_basePage;
|
||||
QGIView* m_qgParent;
|
||||
std::string m_qgParentName;
|
||||
|
||||
bool m_inProgressLock;
|
||||
|
||||
QPushButton* m_btnOK;
|
||||
QPushButton* m_btnCancel;
|
||||
|
||||
Base::Vector3d m_saveAnchor;
|
||||
double m_saveRadius;
|
||||
bool m_saved;
|
||||
QPointF m_dragStart;
|
||||
|
||||
std::string m_baseName;
|
||||
std::string m_pageName;
|
||||
std::string m_detailName;
|
||||
App::Document* m_doc;
|
||||
|
||||
bool m_mode;
|
||||
bool m_created;
|
||||
};
|
||||
|
||||
class TaskDlgDetail : public Gui::TaskView::TaskDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
TaskDlgDetail(TechDraw::DrawViewPart* baseFeat);
|
||||
TaskDlgDetail(TechDraw::DrawViewDetail* detailFeat);
|
||||
~TaskDlgDetail();
|
||||
|
||||
public:
|
||||
/// is called the TaskView when the dialog is opened
|
||||
virtual void open();
|
||||
/// is called by the framework if an button is clicked which has no accept or reject role
|
||||
virtual void clicked(int);
|
||||
/// is called by the framework if the dialog is accepted (Ok)
|
||||
virtual bool accept();
|
||||
/// is called by the framework if the dialog is rejected (Cancel)
|
||||
virtual bool reject();
|
||||
/// is called by the framework if the user presses the help button
|
||||
virtual void helpRequested() { return;}
|
||||
virtual bool isAllowedAlterDocument(void) const
|
||||
{ return false; }
|
||||
void update();
|
||||
|
||||
void modifyStandardButtons(QDialogButtonBox* box);
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
TaskDetail * widget;
|
||||
Gui::TaskView::TaskBox* taskbox;
|
||||
};
|
||||
|
||||
} //namespace TechDrawGui
|
||||
|
||||
#endif // #ifndef TECHDRAWGUI_TASKCOSVERTEX_H
|
||||
@@ -0,0 +1,296 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>TechDrawGui::TaskDetail</class>
|
||||
<widget class="QWidget" name="TechDrawGui::TaskDetail">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>381</width>
|
||||
<height>405</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>250</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Detail Anchor</string>
|
||||
</property>
|
||||
<property name="windowIcon">
|
||||
<iconset resource="Resources/TechDraw.qrc">
|
||||
<normaloff>:/icons/actions/techdraw-DetailView.svg</normaloff>:/icons/actions/techdraw-DetailView.svg</iconset>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QFrame" name="frame">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>300</width>
|
||||
<height>300</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="baseSize">
|
||||
<size>
|
||||
<width>300</width>
|
||||
<height>300</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Box</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="leBaseView">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="mouseTracking">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="acceptDrops">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Base View</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Detail View</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="leDetailView">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pbDragger">
|
||||
<property name="toolTip">
|
||||
<string>Click to drag detail highlight to new position</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Drag Highlight</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout_2" columnstretch="2,1,2">
|
||||
<item row="2" column="2">
|
||||
<widget class="Gui::QuantitySpinBox" name="qsbRadius">
|
||||
<property name="toolTip">
|
||||
<string>size of detail view</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="unit" stdset="0">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>10.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>X</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Y</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="Gui::QuantitySpinBox" name="qsbX">
|
||||
<property name="toolTip">
|
||||
<string>x position of detail highlight within view</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="unit" stdset="0">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>0.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="Gui::QuantitySpinBox" name="qsbY">
|
||||
<property name="toolTip">
|
||||
<string>y position of detail highlight within view</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="unit" stdset="0">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Radius</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>Reference</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="2">
|
||||
<widget class="Gui::AccelLineEdit" name="aeReference">
|
||||
<property name="toolTip">
|
||||
<string>Detail identifier</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>1</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>Gui::AccelLineEdit</class>
|
||||
<extends>QLineEdit</extends>
|
||||
<header>Gui/Widgets.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>Gui::QuantitySpinBox</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>Gui/QuantitySpinBox.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<include location="Resources/TechDraw.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -376,7 +376,7 @@ void TaskWeldingSymbol::onFlipSidesClicked()
|
||||
ui->leOtherTextR->setText(ui->leArrowTextR->text());
|
||||
ui->leArrowTextR->setText(tempText);
|
||||
|
||||
// one cannot get the path from the icon therfore read out
|
||||
// one cannot get the path from the icon therefore read out
|
||||
// the path property
|
||||
auto tempPathArrow = m_arrowFeat->SymbolFile.getValue();
|
||||
auto tempPathOther = m_otherFeat->SymbolFile.getValue();
|
||||
|
||||
@@ -37,19 +37,29 @@
|
||||
#include <App/Application.h>
|
||||
#include <App/Document.h>
|
||||
#include <App/DocumentObject.h>
|
||||
#include <Gui/Application.h>
|
||||
#include <Gui/Command.h>
|
||||
#include <Gui/Control.h>
|
||||
#include <Gui/Document.h>
|
||||
#include <Gui/MainWindow.h>
|
||||
#include <Gui/Selection.h>
|
||||
#include <Gui/ViewProvider.h>
|
||||
#include <Gui/WaitCursor.h>
|
||||
|
||||
#include <Mod/TechDraw/App/DrawViewDimension.h>
|
||||
#include <Mod/TechDraw/App/DrawViewBalloon.h>
|
||||
#include <Mod/TechDraw/App/DrawLeaderLine.h>
|
||||
#include <Mod/TechDraw/App/DrawRichAnno.h>
|
||||
#include <Mod/TechDraw/App/DrawViewMulti.h>
|
||||
#include <Mod/TechDraw/App/DrawViewDetail.h>
|
||||
#include <Mod/TechDraw/App/DrawHatch.h>
|
||||
#include <Mod/TechDraw/App/DrawGeomHatch.h>
|
||||
#include <Mod/TechDraw/App/DrawWeldSymbol.h>
|
||||
#include <Mod/TechDraw/App/LineGroup.h>
|
||||
|
||||
#include<Mod/TechDraw/App/DrawPage.h>
|
||||
#include "QGIView.h"
|
||||
#include "TaskDetail.h"
|
||||
#include "ViewProviderViewPart.h"
|
||||
|
||||
using namespace TechDrawGui;
|
||||
@@ -166,8 +176,11 @@ void ViewProviderViewPart::onChanged(const App::Property* prop)
|
||||
void ViewProviderViewPart::attach(App::DocumentObject *pcFeat)
|
||||
{
|
||||
TechDraw::DrawViewMulti* dvm = dynamic_cast<TechDraw::DrawViewMulti*>(pcFeat);
|
||||
TechDraw::DrawViewDetail* dvd = dynamic_cast<TechDraw::DrawViewDetail*>(pcFeat);
|
||||
if (dvm != nullptr) {
|
||||
sPixmap = "TechDraw_Tree_Multi";
|
||||
} else if (dvd != nullptr) {
|
||||
sPixmap = "actions/techdraw-DetailView";
|
||||
}
|
||||
|
||||
ViewProviderDrawingView::attach(pcFeat);
|
||||
@@ -232,6 +245,57 @@ std::vector<App::DocumentObject*> ViewProviderViewPart::claimChildren(void) cons
|
||||
return tmp;
|
||||
}
|
||||
}
|
||||
bool ViewProviderViewPart::setEdit(int ModNum)
|
||||
{
|
||||
if (ModNum == ViewProvider::Default ) {
|
||||
if (Gui::Control().activeDialog()) { //TaskPanel already open!
|
||||
return false;
|
||||
}
|
||||
TechDraw::DrawViewPart* dvp = getViewObject();
|
||||
TechDraw::DrawViewDetail* dvd = dynamic_cast<TechDraw::DrawViewDetail*>(dvp);
|
||||
if (dvd != nullptr) {
|
||||
// clear the selection (convenience)
|
||||
Gui::Selection().clearSelection();
|
||||
Gui::Control().showDialog(new TaskDlgDetail(dvd));
|
||||
// Gui::Selection().clearSelection();
|
||||
// flush any lingering gui objects
|
||||
Gui::Selection().addSelection(dvd->getDocument()->getName(),
|
||||
dvd->getNameInDocument());
|
||||
Gui::Selection().clearSelection();
|
||||
Gui::Selection().addSelection(dvd->getDocument()->getName(),
|
||||
dvd->getNameInDocument());
|
||||
|
||||
//Gui.ActiveDocument.resetEdit()
|
||||
//>>> # Gui.Selection.addSelection('aaStart121','Detail')
|
||||
//>>> # Gui.Selection.clearSelection()
|
||||
//>>> # Gui.Selection.addSelection('aaStart121','Detail')
|
||||
//>>> # Gui.Selection.addSelection('aaStart121','Detail')
|
||||
//>>> # Gui.Selection.clearSelection()
|
||||
//>>> # Gui.Selection.addSelection('aaStart121','Detail')
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
return ViewProviderDrawingView::setEdit(ModNum);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void ViewProviderViewPart::unsetEdit(int ModNum)
|
||||
{
|
||||
Q_UNUSED(ModNum);
|
||||
if (ModNum == ViewProvider::Default) {
|
||||
Gui::Control().closeDialog();
|
||||
}
|
||||
else {
|
||||
ViewProviderDrawingView::unsetEdit(ModNum);
|
||||
}
|
||||
}
|
||||
|
||||
bool ViewProviderViewPart::doubleClicked(void)
|
||||
{
|
||||
setEdit(ViewProvider::Default);
|
||||
return true;
|
||||
}
|
||||
|
||||
TechDraw::DrawViewPart* ViewProviderViewPart::getViewObject() const
|
||||
{
|
||||
|
||||
@@ -68,6 +68,9 @@ public:
|
||||
virtual std::vector<std::string> getDisplayModes(void) const;
|
||||
virtual bool onDelete(const std::vector<std::string> &);
|
||||
virtual bool canDelete(App::DocumentObject* obj) const;
|
||||
virtual bool setEdit(int ModNum);
|
||||
virtual void unsetEdit(int ModNum);
|
||||
virtual bool doubleClicked(void);
|
||||
|
||||
public:
|
||||
virtual void onChanged(const App::Property *prop);
|
||||
|
||||
Reference in New Issue
Block a user