# -*- coding: utf-8 -*- # *************************************************************************** # * Copyright (c) 2009, 2010 Yorik van Havre * # * Copyright (c) 2009, 2010 Ken Cline * # * * # * 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 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 functionality of the module is divided into GUI tools, usable from the # visual interface, and corresponding python functions, that can perform # the same operation programmatically. # # @{ 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 import Draft_rc gui = True # To prevent complaints from code checkers (flake8) True if Draft_rc.__name__ else False else: gui = False __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 # --------------------------------------------------------------------------- from DraftLayer import Layer as _VisGroup from DraftLayer import ViewProviderLayer as _ViewProviderVisGroup from DraftLayer import makeLayer # --------------------------------------------------------------------------- # General functions # --------------------------------------------------------------------------- from draftutils.utils import ARROW_TYPES as arrowtypes from draftutils.utils import stringencodecoin from draftutils.utils import string_encode_coin from draftutils.utils import typecheck from draftutils.utils import type_check from draftutils.utils import getParamType from draftutils.utils import get_param_type from draftutils.utils import getParam from draftutils.utils import get_param from draftutils.utils import setParam from draftutils.utils import set_param from draftutils.utils import precision from draftutils.utils import tolerance from draftutils.utils import epsilon from draftutils.utils import getRealName from draftutils.utils import get_real_name from draftutils.utils import getType from draftutils.utils import get_type from draftutils.utils import getObjectsOfType from draftutils.utils import get_objects_of_type from draftutils.utils import isClone from draftutils.utils import is_clone from draftutils.utils import getCloneBase from draftutils.utils import get_clone_base from draftutils.utils import getGroupNames from draftutils.utils import get_group_names from draftutils.utils import ungroup from draftutils.utils import getGroupContents from draftutils.utils import get_group_contents from draftutils.utils import printShape from draftutils.utils import print_shape from draftutils.utils import compareObjects from draftutils.utils import compare_objects from draftutils.utils import shapify from draftutils.utils import loadSvgPatterns from draftutils.utils import load_svg_patterns from draftutils.utils import svgpatterns from draftutils.utils import svg_patterns from draftutils.utils import getMovableChildren from draftutils.utils import get_movable_children from draftutils.utils import filter_objects_for_modifiers from draftutils.utils import filterObjectsForModifiers from draftutils.utils import is_closed_edge from draftutils.utils import isClosedEdge from draftutils.gui_utils import get3DView from draftutils.gui_utils import get_3d_view from draftutils.gui_utils import autogroup from draftutils.gui_utils import dimSymbol from draftutils.gui_utils import dim_symbol from draftutils.gui_utils import dimDash from draftutils.gui_utils import dim_dash from draftutils.gui_utils import removeHidden from draftutils.gui_utils import remove_hidden from draftutils.gui_utils import formatObject from draftutils.gui_utils import format_object from draftutils.gui_utils import getSelection from draftutils.gui_utils import get_selection from draftutils.gui_utils import getSelectionEx from draftutils.gui_utils import get_selection_ex from draftutils.gui_utils import select from draftutils.gui_utils import loadTexture from draftutils.gui_utils import load_texture #--------------------------------------------------------------------------- # Draft functions #--------------------------------------------------------------------------- from draftfunctions.array import array from draftfunctions.cut import cut from draftfunctions.downgrade import downgrade from draftfunctions.draftify import draftify from draftfunctions.extrude import extrude from draftfunctions.fuse import fuse from draftfunctions.heal import heal from draftfunctions.move import move from draftfunctions.move import move_vertex, moveVertex from draftfunctions.move import move_edge, moveEdge from draftfunctions.move import copy_moved_edges, copyMovedEdges from draftfunctions.rotate import rotate from draftfunctions.rotate import rotate_vertex, rotateVertex from draftfunctions.rotate import rotate_edge, rotateEdge from draftfunctions.rotate import copy_rotated_edges, copyRotatedEdges from draftfunctions.scale import scale from draftfunctions.scale import scale_vertex, scaleVertex from draftfunctions.scale import scale_edge, scaleEdge from draftfunctions.scale import copy_scaled_edges, copyScaledEdges from draftfunctions.join import join_wires from draftfunctions.join import join_wires as joinWires from draftfunctions.join import join_two_wires from draftfunctions.join import join_two_wires as joinTwoWires from draftfunctions.split import split from draftfunctions.offset import offset from draftfunctions.mirror import mirror from draftfunctions.upgrade import upgrade #--------------------------------------------------------------------------- # Draft objects #--------------------------------------------------------------------------- # base object from draftobjects.base import DraftObject from draftobjects.base import _DraftObject # base viewprovider from draftviewproviders.view_base import ViewProviderDraft from draftviewproviders.view_base import _ViewProviderDraft from draftviewproviders.view_base import ViewProviderDraftAlt from draftviewproviders.view_base import _ViewProviderDraftAlt from draftviewproviders.view_base import ViewProviderDraftPart from draftviewproviders.view_base import _ViewProviderDraftPart # App::Link support from draftobjects.draftlink import DraftLink from draftobjects.draftlink import _DraftLink from draftviewproviders.view_draftlink import ViewProviderDraftLink from draftviewproviders.view_draftlink import _ViewProviderDraftLink # circle from draftmake.make_circle import make_circle, makeCircle from draftobjects.circle import Circle, _Circle # arcs from draftmake.make_arc_3points import make_arc_3points # ellipse from draftmake.make_ellipse import make_ellipse, makeEllipse from draftobjects.ellipse import Ellipse, _Ellipse # rectangle from draftmake.make_rectangle import make_rectangle, makeRectangle from draftobjects.rectangle import Rectangle, _Rectangle if FreeCAD.GuiUp: from draftviewproviders.view_rectangle import ViewProviderRectangle from draftviewproviders.view_rectangle import _ViewProviderRectangle # polygon from draftmake.make_polygon import make_polygon, makePolygon from draftobjects.polygon import Polygon, _Polygon # wire and line from draftmake.make_line import make_line, makeLine from draftmake.make_wire import make_wire, makeWire from draftobjects.wire import Wire, _Wire if FreeCAD.GuiUp: from draftviewproviders.view_wire import ViewProviderWire from draftviewproviders.view_wire import _ViewProviderWire # bspline from draftmake.make_bspline import make_bspline, makeBSpline from draftobjects.bspline import BSpline, _BSpline if FreeCAD.GuiUp: from draftviewproviders.view_bspline import ViewProviderBSpline from draftviewproviders.view_bspline import _ViewProviderBSpline # bezcurve from draftmake.make_bezcurve import make_bezcurve, makeBezCurve from draftobjects.bezcurve import BezCurve, _BezCurve if FreeCAD.GuiUp: from draftviewproviders.view_bezcurve import ViewProviderBezCurve from draftviewproviders.view_bezcurve import _ViewProviderBezCurve # copy from draftmake.make_copy import make_copy from draftmake.make_copy import make_copy as makeCopy # clone from draftmake.make_clone import make_clone, clone from draftobjects.clone import Clone, _Clone if FreeCAD.GuiUp: from draftviewproviders.view_clone import ViewProviderClone from draftviewproviders.view_clone import _ViewProviderClone # point from draftmake.make_point import make_point, makePoint from draftobjects.point import Point, _Point if FreeCAD.GuiUp: from draftviewproviders.view_point import ViewProviderPoint from draftviewproviders.view_point import _ViewProviderPoint # facebinder from draftmake.make_facebinder import make_facebinder, makeFacebinder from draftobjects.facebinder import Facebinder, _Facebinder if FreeCAD.GuiUp: from draftviewproviders.view_facebinder import ViewProviderFacebinder from draftviewproviders.view_facebinder import _ViewProviderFacebinder # shapestring from draftmake.make_block import make_block, makeBlock from draftobjects.block import Block, _Block # shapestring from draftmake.make_shapestring import make_shapestring, makeShapeString from draftobjects.shapestring import ShapeString, _ShapeString # shape 2d view from draftmake.make_shape2dview import make_shape2dview, makeShape2DView from draftobjects.shape2dview import Shape2DView, _Shape2DView # sketch from draftmake.make_sketch import make_sketch, makeSketch # working plane proxy from draftmake.make_wpproxy import make_workingplaneproxy from draftmake.make_wpproxy import makeWorkingPlaneProxy from draftobjects.wpproxy import WorkingPlaneProxy if FreeCAD.GuiUp: from draftviewproviders.view_wpproxy import ViewProviderWorkingPlaneProxy from draftmake.make_fillet import make_fillet from draftobjects.fillet import Fillet if FreeCAD.GuiUp: from draftviewproviders.view_fillet import ViewProviderFillet #--------------------------------------------------------------------------- # Draft annotation objects #--------------------------------------------------------------------------- from draftobjects.dimension import make_dimension, make_angular_dimension from draftobjects.dimension import LinearDimension, AngularDimension makeDimension = make_dimension makeAngularDimension = make_angular_dimension _Dimension = LinearDimension _AngularDimension = AngularDimension if gui: from draftviewproviders.view_dimension import ViewProviderLinearDimension from draftviewproviders.view_dimension import ViewProviderAngularDimension _ViewProviderDimension = ViewProviderLinearDimension _ViewProviderAngularDimension = ViewProviderAngularDimension from draftobjects.label import make_label from draftobjects.label import Label makeLabel = make_label DraftLabel = Label if gui: from draftviewproviders.view_label import ViewProviderLabel ViewProviderDraftLabel = ViewProviderLabel from draftobjects.text import make_text from draftobjects.text import Text makeText = make_text DraftText = Text if gui: from draftviewproviders.view_text import ViewProviderText ViewProviderDraftText = ViewProviderText def convertDraftTexts(textslist=[]): """ converts the given Draft texts (or all that is found in the active document) to the new object This function was already present at splitting time during v 0.19 """ if not isinstance(textslist,list): textslist = [textslist] if not textslist: for o in FreeCAD.ActiveDocument.Objects: if o.TypeId == "App::Annotation": textslist.append(o) todelete = [] for o in textslist: l = o.Label o.Label = l+".old" obj = makeText(o.LabelText,point=o.Position) obj.Label = l todelete.append(o.Name) for p in o.InList: if p.isDerivedFrom("App::DocumentObjectGroup"): if o in p.Group: g = p.Group g.append(obj) p.Group = g for n in todelete: FreeCAD.ActiveDocument.removeObject(n) def makeArray(baseobject,arg1,arg2,arg3,arg4=None,arg5=None,arg6=None,name="Array",use_link=False): """makeArray(object,xvector,yvector,xnum,ynum,[name]) for rectangular array, or makeArray(object,xvector,yvector,zvector,xnum,ynum,znum,[name]) for rectangular array, or makeArray(object,center,totalangle,totalnum,[name]) for polar array, or makeArray(object,rdistance,tdistance,axis,center,ncircles,symmetry,[name]) for circular array: Creates an array of the given object with, in case of rectangular array, xnum of iterations in the x direction at xvector distance between iterations, same for y direction with yvector and ynum, same for z direction with zvector and znum. In case of polar array, center is a vector, totalangle is the angle to cover (in degrees) and totalnum is the number of objects, including the original. In case of a circular array, rdistance is the distance of the circles, tdistance is the distance within circles, axis the rotation-axes, center the center of rotation, ncircles the number of circles and symmetry the number of symmetry-axis of the distribution. The result is a parametric Draft Array. """ if not FreeCAD.ActiveDocument: FreeCAD.Console.PrintError("No active document. Aborting\n") return if use_link: obj = FreeCAD.ActiveDocument.addObject("Part::FeaturePython",name,_Array(None),None,True) else: obj = FreeCAD.ActiveDocument.addObject("Part::FeaturePython",name) _Array(obj) obj.Base = baseobject if arg6: if isinstance(arg1, (int, float, FreeCAD.Units.Quantity)): obj.ArrayType = "circular" obj.RadialDistance = arg1 obj.TangentialDistance = arg2 obj.Axis = arg3 obj.Center = arg4 obj.NumberCircles = arg5 obj.Symmetry = arg6 else: obj.ArrayType = "ortho" obj.IntervalX = arg1 obj.IntervalY = arg2 obj.IntervalZ = arg3 obj.NumberX = arg4 obj.NumberY = arg5 obj.NumberZ = arg6 elif arg4: obj.ArrayType = "ortho" obj.IntervalX = arg1 obj.IntervalY = arg2 obj.NumberX = arg3 obj.NumberY = arg4 else: obj.ArrayType = "polar" obj.Center = arg1 obj.Angle = arg2 obj.NumberPolar = arg3 if gui: if use_link: _ViewProviderDraftLink(obj.ViewObject) else: _ViewProviderDraftArray(obj.ViewObject) formatObject(obj,obj.Base) if len(obj.Base.ViewObject.DiffuseColor) > 1: obj.ViewObject.Proxy.resetColors(obj.ViewObject) baseobject.ViewObject.hide() select(obj) return obj def makePathArray(baseobject,pathobject,count,xlate=None,align=False,pathobjsubs=[],use_link=False): """makePathArray(docobj,path,count,xlate,align,pathobjsubs,use_link): distribute count copies of a document baseobject along a pathobject or subobjects of a pathobject. Optionally translates each copy by FreeCAD.Vector xlate direction and distance to adjust for difference in shape centre vs shape reference point. Optionally aligns baseobject to tangent/normal/binormal of path.""" if not FreeCAD.ActiveDocument: FreeCAD.Console.PrintError("No active document. Aborting\n") return if use_link: obj = FreeCAD.ActiveDocument.addObject("Part::FeaturePython","PathArray",_PathArray(None),None,True) else: obj = FreeCAD.ActiveDocument.addObject("Part::FeaturePython","PathArray") _PathArray(obj) obj.Base = baseobject obj.PathObj = pathobject if pathobjsubs: sl = [] for sub in pathobjsubs: sl.append((obj.PathObj,sub)) obj.PathSubs = list(sl) if count > 1: obj.Count = count if xlate: obj.Xlate = xlate obj.Align = align if gui: if use_link: _ViewProviderDraftLink(obj.ViewObject) else: _ViewProviderDraftArray(obj.ViewObject) formatObject(obj,obj.Base) if len(obj.Base.ViewObject.DiffuseColor) > 1: obj.ViewObject.Proxy.resetColors(obj.ViewObject) baseobject.ViewObject.hide() select(obj) return obj def makePointArray(base, ptlst): """makePointArray(base,pointlist):""" obj = FreeCAD.ActiveDocument.addObject("Part::FeaturePython","PointArray") _PointArray(obj, base, ptlst) obj.Base = base obj.PointList = ptlst if gui: _ViewProviderDraftArray(obj.ViewObject) base.ViewObject.hide() formatObject(obj,obj.Base) if len(obj.Base.ViewObject.DiffuseColor) > 1: obj.ViewObject.Proxy.resetColors(obj.ViewObject) select(obj) return obj def getDXF(obj,direction=None): """getDXF(object,[direction]): returns a DXF entity from the given object. If direction is given, the object is projected in 2D.""" plane = None result = "" if obj.isDerivedFrom("Drawing::View") or obj.isDerivedFrom("TechDraw::DrawView"): if obj.Source.isDerivedFrom("App::DocumentObjectGroup"): for o in obj.Source.Group: result += getDXF(o,obj.Direction) else: result += getDXF(obj.Source,obj.Direction) return result if direction: if isinstance(direction,FreeCAD.Vector): if direction != Vector(0,0,0): plane = WorkingPlane.plane() plane.alignToPointAndAxis(Vector(0,0,0),direction) def getProj(vec): if not plane: return vec nx = DraftVecUtils.project(vec,plane.u) ny = DraftVecUtils.project(vec,plane.v) return Vector(nx.Length,ny.Length,0) if getType(obj) in ["Dimension","LinearDimension"]: p1 = getProj(obj.Start) p2 = getProj(obj.End) p3 = getProj(obj.Dimline) result += "0\nDIMENSION\n8\n0\n62\n0\n3\nStandard\n70\n1\n" result += "10\n"+str(p3.x)+"\n20\n"+str(p3.y)+"\n30\n"+str(p3.z)+"\n" result += "13\n"+str(p1.x)+"\n23\n"+str(p1.y)+"\n33\n"+str(p1.z)+"\n" result += "14\n"+str(p2.x)+"\n24\n"+str(p2.y)+"\n34\n"+str(p2.z)+"\n" elif getType(obj) == "Annotation": p = getProj(obj.Position) count = 0 for t in obj.LabeLtext: result += "0\nTEXT\n8\n0\n62\n0\n" result += "10\n"+str(p.x)+"\n20\n"+str(p.y+count)+"\n30\n"+str(p.z)+"\n" result += "40\n1\n" result += "1\n"+str(t)+"\n" result += "7\nSTANDARD\n" count += 1 elif hasattr(obj,'Shape'): # TODO do this the Draft way, for ex. using polylines and rectangles import Drawing if not direction: direction = FreeCAD.Vector(0,0,-1) if DraftVecUtils.isNull(direction): direction = FreeCAD.Vector(0,0,-1) try: d = Drawing.projectToDXF(obj.Shape,direction) except: print("Draft.getDXF: Unable to project ",obj.Label," to ",direction) else: result += d else: print("Draft.getDXF: Unsupported object: ",obj.Label) return result def getrgb(color,testbw=True): """getRGB(color,[testbw]): returns a rgb value #000000 from a freecad color if testwb = True (default), pure white will be converted into pure black""" r = str(hex(int(color[0]*255)))[2:].zfill(2) g = str(hex(int(color[1]*255)))[2:].zfill(2) b = str(hex(int(color[2]*255)))[2:].zfill(2) col = "#"+r+g+b if testbw: if col == "#ffffff": #print(getParam('SvgLinesBlack')) if getParam('SvgLinesBlack',True): col = "#000000" return col import getSVG as svg getSVG = svg.getSVG def makeDrawingView(obj,page,lwmod=None,tmod=None,otherProjection=None): """ makeDrawingView(object,page,[lwmod,tmod]) - adds a View of the given object to the given page. lwmod modifies lineweights (in percent), tmod modifies text heights (in percent). The Hint scale, X and Y of the page are used. """ if not FreeCAD.ActiveDocument: FreeCAD.Console.PrintError("No active document. Aborting\n") return if getType(obj) == "SectionPlane": import ArchSectionPlane viewobj = FreeCAD.ActiveDocument.addObject("Drawing::FeatureViewPython","View") page.addObject(viewobj) ArchSectionPlane._ArchDrawingView(viewobj) viewobj.Source = obj viewobj.Label = "View of "+obj.Name elif getType(obj) == "Panel": import ArchPanel viewobj = ArchPanel.makePanelView(obj,page) else: viewobj = FreeCAD.ActiveDocument.addObject("Drawing::FeatureViewPython","View"+obj.Name) _DrawingView(viewobj) page.addObject(viewobj) if (otherProjection): if hasattr(otherProjection,"Scale"): viewobj.Scale = otherProjection.Scale if hasattr(otherProjection,"X"): viewobj.X = otherProjection.X if hasattr(otherProjection,"Y"): viewobj.Y = otherProjection.Y if hasattr(otherProjection,"Rotation"): viewobj.Rotation = otherProjection.Rotation if hasattr(otherProjection,"Direction"): viewobj.Direction = otherProjection.Direction else: if hasattr(page.ViewObject,"HintScale"): viewobj.Scale = page.ViewObject.HintScale if hasattr(page.ViewObject,"HintOffsetX"): viewobj.X = page.ViewObject.HintOffsetX if hasattr(page.ViewObject,"HintOffsetY"): viewobj.Y = page.ViewObject.HintOffsetY viewobj.Source = obj if lwmod: viewobj.LineweightModifier = lwmod if tmod: viewobj.TextModifier = tmod if hasattr(obj.ViewObject,"Pattern"): if str(obj.ViewObject.Pattern) in list(svgpatterns().keys()): viewobj.FillStyle = str(obj.ViewObject.Pattern) if hasattr(obj.ViewObject,"DrawStyle"): viewobj.LineStyle = obj.ViewObject.DrawStyle if hasattr(obj.ViewObject,"LineColor"): viewobj.LineColor = obj.ViewObject.LineColor elif hasattr(obj.ViewObject,"TextColor"): viewobj.LineColor = obj.ViewObject.TextColor return viewobj def getParameterFromV0(edge, offset): """return parameter at distance offset from edge.Vertexes[0] sb method in Part.TopoShapeEdge???""" lpt = edge.valueAt(edge.getParameterByLength(0)) vpt = edge.Vertexes[0].Point if not DraftVecUtils.equals(vpt, lpt): # this edge is flipped length = edge.Length - offset else: # this edge is right way around length = offset return (edge.getParameterByLength(length)) def calculatePlacement(globalRotation, edge, offset, RefPt, xlate, align, normal=None): """Orient shape to tangent at parm offset along edge.""" import functools # http://en.wikipedia.org/wiki/Euler_angles # start with null Placement point so translate goes to right place. placement = FreeCAD.Placement() # preserve global orientation placement.Rotation = globalRotation placement.move(RefPt + xlate) if not align: return placement nullv = FreeCAD.Vector(0, 0, 0) # get a local coord system (tangent, normal, binormal) at parameter offset (normally length) t = edge.tangentAt(getParameterFromV0(edge, offset)) t.normalize() try: n = edge.normalAt(getParameterFromV0(edge, offset)) n.normalize() b = (t.cross(n)) b.normalize() # no normal defined here except FreeCAD.Base.FreeCADError: n = nullv b = nullv FreeCAD.Console.PrintMessage( "Draft PathArray.orientShape - Cannot calculate Path normal.\n") priority = "ZXY" #the default. Doesn't seem to affect results. newRot = FreeCAD.Rotation(t, n, b, priority); newGRot = newRot.multiply(globalRotation) placement.Rotation = newGRot return placement def calculatePlacementsOnPath(shapeRotation, pathwire, count, xlate, align): """Calculates the placements of a shape along a given path so that each copy will be distributed evenly""" import Part import DraftGeomUtils closedpath = DraftGeomUtils.isReallyClosed(pathwire) normal = DraftGeomUtils.getNormal(pathwire) path = Part.__sortEdges__(pathwire.Edges) ends = [] cdist = 0 for e in path: # find cumulative edge end distance cdist += e.Length ends.append(cdist) placements = [] # place the start shape pt = path[0].Vertexes[0].Point placements.append(calculatePlacement( shapeRotation, path[0], 0, pt, xlate, align, normal)) # closed path doesn't need shape on last vertex if not(closedpath): # place the end shape pt = path[-1].Vertexes[-1].Point placements.append(calculatePlacement( shapeRotation, path[-1], path[-1].Length, pt, xlate, align, normal)) if count < 3: return placements # place the middle shapes if closedpath: stop = count else: stop = count - 1 step = float(cdist) / stop remains = 0 travel = step for i in range(1, stop): # which edge in path should contain this shape? # avoids problems with float math travel > ends[-1] iend = len(ends) - 1 for j in range(0, len(ends)): if travel <= ends[j]: iend = j break # place shape at proper spot on proper edge remains = ends[iend] - travel offset = path[iend].Length - remains pt = path[iend].valueAt(getParameterFromV0(path[iend], offset)) placements.append(calculatePlacement( shapeRotation, path[iend], offset, pt, xlate, align, normal)) travel += step return placements #--------------------------------------------------------------------------- # Python Features definitions #--------------------------------------------------------------------------- import draftobjects.base _DraftObject = draftobjects.base.DraftObject class _DrawingView(_DraftObject): """The Draft DrawingView object""" def __init__(self, obj): _DraftObject.__init__(self,obj,"DrawingView") obj.addProperty("App::PropertyVector","Direction","Shape View",QT_TRANSLATE_NOOP("App::Property","Projection direction")) obj.addProperty("App::PropertyFloat","LineWidth","View Style",QT_TRANSLATE_NOOP("App::Property","The width of the lines inside this object")) obj.addProperty("App::PropertyLength","FontSize","View Style",QT_TRANSLATE_NOOP("App::Property","The size of the texts inside this object")) obj.addProperty("App::PropertyLength","LineSpacing","View Style",QT_TRANSLATE_NOOP("App::Property","The spacing between lines of text")) obj.addProperty("App::PropertyColor","LineColor","View Style",QT_TRANSLATE_NOOP("App::Property","The color of the projected objects")) obj.addProperty("App::PropertyLink","Source","Base",QT_TRANSLATE_NOOP("App::Property","The linked object")) obj.addProperty("App::PropertyEnumeration","FillStyle","View Style",QT_TRANSLATE_NOOP("App::Property","Shape Fill Style")) obj.addProperty("App::PropertyEnumeration","LineStyle","View Style",QT_TRANSLATE_NOOP("App::Property","Line Style")) obj.addProperty("App::PropertyBool","AlwaysOn","View Style",QT_TRANSLATE_NOOP("App::Property","If checked, source objects are displayed regardless of being visible in the 3D model")) obj.FillStyle = ['shape color'] + list(svgpatterns().keys()) obj.LineStyle = ['Solid','Dashed','Dotted','Dashdot'] obj.LineWidth = 0.35 obj.FontSize = 12 def execute(self, obj): result = "" if hasattr(obj,"Source"): if obj.Source: if hasattr(obj,"LineStyle"): ls = obj.LineStyle else: ls = None if hasattr(obj,"LineColor"): lc = obj.LineColor else: lc = None if hasattr(obj,"LineSpacing"): lp = obj.LineSpacing else: lp = None if obj.Source.isDerivedFrom("App::DocumentObjectGroup"): svg = "" shapes = [] others = [] objs = getGroupContents([obj.Source]) for o in objs: v = o.ViewObject.isVisible() if hasattr(obj,"AlwaysOn"): if obj.AlwaysOn: v = True if v: svg += getSVG(o,obj.Scale,obj.LineWidth,obj.FontSize.Value,obj.FillStyle,obj.Direction,ls,lc,lp) else: svg = getSVG(obj.Source,obj.Scale,obj.LineWidth,obj.FontSize.Value,obj.FillStyle,obj.Direction,ls,lc,lp) result += ' 0: obj.Shape = Part.makeCompound(base) else: FreeCAD.Console.PrintError(translate("draft","No point found\n")) obj.Shape = obj.Base.Shape.copy() class _ViewProviderDraftArray(_ViewProviderDraft): """a view provider that displays a Array icon instead of a Draft icon""" def __init__(self,vobj): _ViewProviderDraft.__init__(self,vobj) def getIcon(self): if hasattr(self.Object, "ArrayType"): if self.Object.ArrayType == 'ortho': return ":/icons/Draft_Array.svg" elif self.Object.ArrayType == 'polar': return ":/icons/Draft_PolarArray.svg" elif self.Object.ArrayType == 'circular': return ":/icons/Draft_CircularArray.svg" elif hasattr(self.Object, "PointList"): return ":/icons/Draft_PointArray.svg" else: return ":/icons/Draft_PathArray.svg" def resetColors(self, vobj): colors = [] if vobj.Object.Base: if vobj.Object.Base.isDerivedFrom("Part::Feature"): if len(vobj.Object.Base.ViewObject.DiffuseColor) > 1: colors = vobj.Object.Base.ViewObject.DiffuseColor else: c = vobj.Object.Base.ViewObject.ShapeColor c = (c[0],c[1],c[2],vobj.Object.Base.ViewObject.Transparency/100.0) for f in vobj.Object.Base.Shape.Faces: colors.append(c) if colors: n = 1 if hasattr(vobj.Object,"ArrayType"): if vobj.Object.ArrayType == "ortho": n = vobj.Object.NumberX * vobj.Object.NumberY * vobj.Object.NumberZ else: n = vobj.Object.NumberPolar elif hasattr(vobj.Object,"Count"): n = vobj.Object.Count colors = colors * n vobj.DiffuseColor = colors ## @}