def clone(self, obj): "if this object is a clone, sets the shape. Returns True if this is the case" if hasattr(obj, "CloneOf"): if obj.CloneOf: if Draft.getType(obj.CloneOf) == Draft.getType(obj): pl = obj.Placement obj.Shape = obj.CloneOf.Shape.copy() obj.Placement = pl if hasattr(obj, "BaseMaterial"): if hasattr(obj.CloneOf, "BaseMaterial"): obj.BaseMaterial = obj.CloneOf.BaseMaterial for prop in [ "Length", "Width", "Height", "Thickness", "Area", "PerimeterLength", "HorizontalArea", "VerticalArea", ]: if hasattr(obj, prop) and hasattr(obj.CloneOf, prop): setattr(obj, prop, getattr(obj.CloneOf, prop)) return True return False
def mergeCells(objectslist): """mergeCells(objectslist): merges the objects in the given list into one. All objects must be of the same type and based on the Cell object (cells, floors, buildings, or sites).""" if not objectslist: return None if not isinstance(objectslist, list): return None if len(objectslist) < 2: return None typ = Draft.getType(objectslist[0]) if not (typ in ["Cell", "Floor", "Building", "Site"]): return None for o in objectslist: if Draft.getType(o) != typ: return None base = objectslist.pop(0) for o in objectslist: l = base.Components for c in o.Components: if not c in l: l.append(c) base.Components = l FreeCAD.ActiveDocument.removeObject(o.Name) FreeCAD.ActiveDocument.recompute() return base
def setTrackers(self): v = Draft.get3DView() if v in self.trackers[0]: i = self.trackers[0].index(v) self.grid = self.trackers[1][i] self.tracker = self.trackers[2][i] self.extLine = self.trackers[3][i] self.radiusTracker = self.trackers[4][i] self.dim1 = self.trackers[5][i] self.dim2 = self.trackers[6][i] else: if Draft.getParam("grid"): self.grid = DraftTrackers.gridTracker() else: self.grid = None self.tracker = DraftTrackers.snapTracker() self.extLine = DraftTrackers.lineTracker(dotted=True) self.radiusTracker = DraftTrackers.radiusTracker() self.dim1 = DraftTrackers.archDimTracker(mode=2) self.dim2 = DraftTrackers.archDimTracker(mode=3) self.trackers[0].append(v) self.trackers[1].append(self.grid) self.trackers[2].append(self.tracker) self.trackers[3].append(self.extLine) self.trackers[4].append(self.radiusTracker) self.trackers[5].append(self.dim1) self.trackers[6].append(self.dim2) if self.grid and (not self.forceGridOff): self.grid.set()
def check(objectslist, includehidden=False): """check(objectslist,includehidden=False): checks if the given objects contain only solids""" objs = Draft.getGroupContents(objectslist) if not includehidden: objs = Draft.removeHidden(objs) bad = [] for o in objs: if not o.isDerivedFrom("Part::Feature"): bad.append([o, "is not a Part-based object"]) else: s = o.Shape if (not s.isClosed()) and (not (Draft.getType(o) == "Axis")): bad.append([o, translate("Arch", "is not closed")]) elif not s.isValid(): bad.append([o, translate("Arch", "is not valid")]) elif (not s.Solids) and (not (Draft.getType(o) == "Axis")): bad.append([o, translate("Arch", "doesn't contain any solid")]) else: f = 0 for sol in s.Solids: f += len(sol.Faces) if not sol.isClosed(): bad.append([o, translate("Arch", "contains a non-closed solid")]) if len(s.Faces) != f: bad.append([o, translate("Arch", "contains faces that are not part of any solid")]) return bad
def Activated(self): sel = FreeCADGui.Selection.getSelection() if sel: if Draft.getType(sel[0]) == "Wall": FreeCADGui.activateWorkbench("SketcherWorkbench") FreeCADGui.runCommand("Sketcher_NewSketch") FreeCAD.ArchObserver = ArchComponent.ArchSelectionObserver(sel[0],FreeCAD.ActiveDocument.Objects[-1],hide=False,nextCommand="Arch_Window") FreeCADGui.Selection.addObserver(FreeCAD.ArchObserver) else: FreeCAD.ActiveDocument.openTransaction(str(translate("Arch","Create Window"))) FreeCADGui.doCommand("import Arch") for obj in sel: FreeCADGui.doCommand("Arch.makeWindow(FreeCAD.ActiveDocument."+obj.Name+")") if hasattr(obj,"Support"): if obj.Support: if isinstance(obj.Support,tuple): s = obj.Support[0] else: s = obj.Support w = FreeCAD.ActiveDocument.Objects[-1] # last created object FreeCADGui.doCommand("Arch.removeComponents(FreeCAD.ActiveDocument."+w.Name+",host=FreeCAD.ActiveDocument."+s.Name+")") elif Draft.isClone(obj,"Window"): if obj.Objects[0].Inlist: FreeCADGui.doCommand("Arch.removeComponents(FreeCAD.ActiveDocument."+obj.Name+",host=FreeCAD.ActiveDocument."+obj.Objects[0].Inlist[0].Name+")") FreeCAD.ActiveDocument.commitTransaction()
def makeWindow(baseobj=None,width=None,name="Window"): '''makeWindow(obj,[name]): creates a window based on the given object''' if baseobj: if Draft.getType(baseobj) == "Window": obj = Draft.clone(baseobj) return obj obj = FreeCAD.ActiveDocument.addObject("Part::FeaturePython",name) _Window(obj) _ViewProviderWindow(obj.ViewObject) if baseobj: obj.Base = baseobj if width: obj.WindowParts = ["Default","Panel","Wire0",str(width),"0"] else: obj.WindowParts = makeDefaultWindowPart(baseobj) if obj.Base: obj.Base.ViewObject.DisplayMode = "Wireframe" obj.Base.ViewObject.hide() p = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Arch") c = p.GetUnsigned("WindowColor") r = float((c>>24)&0xFF)/255.0 g = float((c>>16)&0xFF)/255.0 b = float((c>>8)&0xFF)/255.0 obj.ViewObject.ShapeColor = (r,g,b,1.0) return obj
def assemble(self): App.ActiveDocument=App.getDocument(self.name) shape = App.ActiveDocument.ActiveObject.Shape App.ActiveDocument=App.getDocument("PrinterAssembly") App.ActiveDocument.addObject('Part::Feature',self.name).Shape= shape #Color Part #Get the feature and move it into position objs = App.ActiveDocument.getObjectsByLabel(self.name) shape = objs[-1] #Rotate into correct orientation rotateAngle = 90 rotateCenter = App.Vector(0,0,0) rotateAxis = App.Vector(0,0,1) Draft.rotate([shape],rotateAngle,rotateCenter,axis = rotateAxis,copy=False) #Define shifts and move the left clamp into place xShift = gv.zRodSpacing/2 yShift = -gv.yRodLength/2 + gv.frameWidth zShift = -gv.yRodStandoff - gv.frameHeight/2 - gv.frameSpacerLength - gv.frameHeight App.ActiveDocument=App.getDocument("PrinterAssembly") Draft.move([shape],App.Vector(xShift, yShift, zShift),copy=False) App.ActiveDocument.recompute()
def removeShape(objs, mark=True): """takes an arch object (wall or structure) built on a cubic shape, and removes the inner shape, keeping its length, width and height as parameters.""" import DraftGeomUtils if not isinstance(objs, list): objs = [objs] for obj in objs: if DraftGeomUtils.isCubic(obj.Shape): dims = DraftGeomUtils.getCubicDimensions(obj.Shape) if dims: name = obj.Name tp = Draft.getType(obj) print tp if tp == "Structure": FreeCAD.ActiveDocument.removeObject(name) import ArchStructure str = ArchStructure.makeStructure(length=dims[1], width=dims[2], height=dims[3], name=name) str.Placement = dims[0] elif tp == "Wall": FreeCAD.ActiveDocument.removeObject(name) import ArchWall length = dims[1] width = dims[2] v1 = Vector(length / 2, 0, 0) v2 = v1.negative() v1 = dims[0].multVec(v1) v2 = dims[0].multVec(v2) line = Draft.makeLine(v1, v2) wal = ArchWall.makeWall(line, width=width, height=dims[3], name=name) else: if mark: obj.ViewObject.ShapeColor = (1.0, 0.0, 0.0, 1.0)
def Activated(self): sel = FreeCADGui.Selection.getSelection() if Draft.getType(sel[-1]) == "Space": FreeCAD.ActiveDocument.openTransaction(str(translate("Arch", "Remove space boundary"))) FreeCADGui.doCommand("import Arch") FreeCADGui.doCommand( "Arch.removeSpaceBoundaries( FreeCAD.ActiveDocument." + sel[-1].Name + ", FreeCADGui.Selection.getSelection() )" ) else: FreeCAD.ActiveDocument.openTransaction(str(translate("Arch", "Ungrouping"))) if (Draft.getType(sel[-1]) in ["Wall", "Structure", "Stairs", "Roof", "Window"]) and (len(sel) > 1): host = sel.pop() ss = "[" for o in sel: if len(ss) > 1: ss += "," ss += "FreeCAD.ActiveDocument." + o.Name ss += "]" FreeCADGui.doCommand("import Arch") FreeCADGui.doCommand("Arch.removeComponents(" + ss + ",FreeCAD.ActiveDocument." + host.Name + ")") else: FreeCADGui.doCommand("import Arch") FreeCADGui.doCommand("Arch.removeComponents(FreeCAD.ActiveDocument." + sel[-1].Name + ")") FreeCAD.ActiveDocument.commitTransaction() FreeCAD.ActiveDocument.recompute()
def assemble(self): App.ActiveDocument=App.getDocument(self.name) shape = App.ActiveDocument.ActiveObject.Shape App.ActiveDocument=App.getDocument("PrinterAssembly") Gui.ActiveDocument=Gui.getDocument("PrinterAssembly") App.ActiveDocument.addObject('Part::Feature',self.name).Shape= shape #Color Part Gui.ActiveDocument.getObject(self.name).ShapeColor = (gv.frameR,gv.frameG,gv.frameB,gv.frameA) #Get the feature and move it into position objs = App.ActiveDocument.getObjectsByLabel(self.name) shape = objs[-1] # #Rotate into correct orientation # rotateAngle = 0 # rotateCenter = App.Vector(0,0,0) # rotateAxis = App.Vector(1,0,0) # Draft.rotate([shape],rotateAngle,rotateCenter,axis = rotateAxis,copy=False) #Define shifts and move the left clamp into place xShift = -gv.crossBarLength/2 yShift = -gv.yRodLength/2 + gv.frameWidth/2 zShift = -gv.yRodStandoff - 1.5*gv.frameHeight - gv.frameSpacerLength App.ActiveDocument=App.getDocument("PrinterAssembly") Draft.move([shape],App.Vector(xShift, yShift, zShift),copy=False) App.ActiveDocument.recompute()
def makeStructuralSystem(objects=[],axes=[],name="StructuralSystem"): '''makeStructuralSystem(objects,axes): makes a structural system based on the given objects and axes''' result = [] if not axes: print "At least one axis must be given" return if objects: if not isinstance(objects,list): objects = [objects] else: objects = [None] for o in objects: obj = FreeCAD.ActiveDocument.addObject("Part::FeaturePython",name) obj.Label = translate("Arch",name) _StructuralSystem(obj) if FreeCAD.GuiUp: _ViewProviderStructuralSystem(obj.ViewObject) if o: obj.Base = o obj.Axes = axes result.append(obj) if FreeCAD.GuiUp and o: o.ViewObject.hide() Draft.formatObject(obj,o) FreeCAD.ActiveDocument.recompute() if len(result) == 1: return result[0] else: return result
def Activated(self): global QtGui, QtCore from PyQt4 import QtGui, QtCore self.Length = 0.5 self.Width = 0.2 self.Height = 1 self.continueCmd = False sel = FreeCADGui.Selection.getSelection() if sel: # direct creation FreeCAD.ActiveDocument.openTransaction(str(translate("Arch","Create Structure"))) FreeCADGui.doCommand("import Arch") # if selection contains structs and axes, make a system st = Draft.getObjectsOfType(sel,"Structure") ax = Draft.getObjectsOfType(sel,"Axis") if st and ax: FreeCADGui.doCommand("Arch.makeStructuralSystem(" + ArchCommands.getStringList(st) + "," + ArchCommands.getStringList(ax) + ")") else: # else, do normal structs for obj in sel: FreeCADGui.doCommand("Arch.makeStructure(FreeCAD.ActiveDocument." + obj.Name + ")") FreeCAD.ActiveDocument.commitTransaction() FreeCAD.ActiveDocument.recompute() else: # interactive mode import DraftTrackers self.points = [] self.tracker = DraftTrackers.boxTracker() self.tracker.width(self.Width) self.tracker.height(self.Height) self.tracker.length(self.Length) self.tracker.on() FreeCADGui.Snapper.getPoint(callback=self.getPoint,movecallback=self.update,extradlg=self.taskbox())
def __init__(self): # getting screen distance p1 = Draft.get3DView().getPoint((100,100)) p2 = Draft.get3DView().getPoint((110,100)) bl = (p2.sub(p1)).Length * (Draft.getParam("snapRange",5)/2) pick = coin.SoPickStyle() pick.style.setValue(coin.SoPickStyle.UNPICKABLE) self.trans = coin.SoTransform() self.trans.translation.setValue([0,0,0]) m1 = coin.SoMaterial() m1.transparency.setValue(0.8) m1.diffuseColor.setValue([0.4,0.4,0.6]) c1 = coin.SoCoordinate3() c1.point.setValues([[-bl,-bl,0],[bl,-bl,0],[bl,bl,0],[-bl,bl,0]]) f = coin.SoIndexedFaceSet() f.coordIndex.setValues([0,1,2,3]) m2 = coin.SoMaterial() m2.transparency.setValue(0.7) m2.diffuseColor.setValue([0.2,0.2,0.3]) c2 = coin.SoCoordinate3() c2.point.setValues([[0,bl,0],[0,0,0],[bl,0,0],[-.05*bl,.95*bl,0],[0,bl,0], [.05*bl,.95*bl,0],[.95*bl,.05*bl,0],[bl,0,0],[.95*bl,-.05*bl,0]]) l = coin.SoLineSet() l.numVertices.setValues([3,3,3]) s = coin.SoSeparator() s.addChild(pick) s.addChild(self.trans) s.addChild(m1) s.addChild(c1) s.addChild(f) s.addChild(m2) s.addChild(c2) s.addChild(l) Tracker.__init__(self,children=[s],name="planeTracker")
def Activated(self): walls = FreeCADGui.Selection.getSelection() if len(walls) == 1: if Draft.getType(walls[0]) == "Wall": ostr = "FreeCAD.ActiveDocument."+ walls[0].Name ok = False for o in walls[0].Additions: if Draft.getType(o) == "Wall": ostr += ",FreeCAD.ActiveDocument." + o.Name ok = True if ok: FreeCAD.ActiveDocument.openTransaction(str(translate("Arch","Merge Wall"))) FreeCADGui.doCommand("import Arch") FreeCADGui.doCommand("Arch.joinWalls(["+ostr+"],delete=True)") FreeCAD.ActiveDocument.commitTransaction() return else: FreeCAD.Console.PrintWarning(str(translate("Arch","The selected wall contain no subwall to merge"))) return else: FreeCAD.Console.PrintWarning(str(translate("Arch","Please select only wall objects"))) return for w in walls: if Draft.getType(w) != "Wall": FreeCAD.Console.PrintMessage(str(translate("Arch","Please select only wall objects"))) return FreeCAD.ActiveDocument.openTransaction(str(translate("Arch","Merge Walls"))) FreeCADGui.doCommand("import Arch") FreeCADGui.doCommand("Arch.joinWalls(FreeCADGui.Selection.getSelection(),delete=True)") FreeCAD.ActiveDocument.commitTransaction()
def joinWalls(walls,delete=False): """joins the given list of walls into one sketch-based wall. If delete is True, merged wall objects are deleted""" if not walls: return None if not isinstance(walls,list): walls = [walls] if not areSameWallTypes(walls): return None deleteList = [] base = walls.pop() if base.Base: if base.Base.Shape.Faces: return None if Draft.getType(base.Base) == "Sketch": sk = base.Base else: sk = Draft.makeSketch(base.Base,autoconstraints=True) if sk: base.Base = sk for w in walls: if w.Base: if not w.Base.Shape.Faces: for e in w.Base.Shape.Edges: sk.addGeometry(e.Curve) deleteList.append(w.Name) if delete: for n in deleteList: FreeCAD.ActiveDocument.removeObject(n) FreeCAD.ActiveDocument.recompute() base.ViewObject.show() return base
def Activated(self): import Draft from DraftTools import translate sel = FreeCADGui.Selection.getSelection() if (len(sel) == 1) and Draft.getType(sel[0]) == "Spreadsheet": n = FreeCADGui.Selection.getSelection()[0].Name FreeCAD.ActiveDocument.openTransaction(str(translate("Spreadsheet","Add property controller"))) FreeCADGui.doCommand("import Spreadsheet") FreeCADGui.doCommand("Spreadsheet.makeSpreadsheetPropertyController(FreeCAD.ActiveDocument."+n+")") FreeCAD.ActiveDocument.commitTransaction() FreeCAD.ActiveDocument.recompute() elif (len(sel) == 2): if (Draft.getType(sel[0]) == "Spreadsheet") and (Draft.getType(sel[1]) == "SpreadsheetPropertyController"): s = sel[0].Name o = sel[1].Name elif (Draft.getType(sel[1]) == "Spreadsheet") and (Draft.getType(sel[0]) == "SpreadsheetPropertyController"): s = sel[1].Name o = sel[0].Name else: return FreeCAD.ActiveDocument.openTransaction(str(translate("Spreadsheet","Add property controller"))) FreeCADGui.doCommand("import Spreadsheet") FreeCADGui.doCommand("Spreadsheet.makeSpreadsheetPropertyController(FreeCAD.ActiveDocument."+s+",FreeCAD.ActiveDocument."+o+")") FreeCAD.ActiveDocument.commitTransaction() FreeCAD.ActiveDocument.recompute()
def assemble(self): App.ActiveDocument=App.getDocument(self.name) shape = App.ActiveDocument.ActiveObject.Shape App.ActiveDocument=App.getDocument("PrinterAssembly") Gui.ActiveDocument=Gui.getDocument("PrinterAssembly") App.ActiveDocument.addObject('Part::Feature',self.name).Shape= shape #Color Part # Gui.ActiveDocument.getObject(self.name).ShapeColor = (gv.printedR,gv.printedG,gv.printedB,gv.printedA) #Get the feature and move it into position objs = App.ActiveDocument.getObjectsByLabel(self.name) shape = objs[-1] #Rotate into correct orientation rotateAngle = 180 rotateCenter = App.Vector(0,0,0) rotateAxis = App.Vector(0,0,1) Draft.rotate([shape],rotateAngle,rotateCenter,axis = rotateAxis,copy=False) #Define shifts and move the left clamp into place xShift = 0 yShift = ( gv.extruderDepth - gv.extruderEdgeToCenterLine) zShift = (-gv.xCarriageBushingHolderOR + gv.xCarriageMountHoleVertOffset - (gv.extruderMountAngleWidth-gv.extruderMountAngleThickness)/2 ) App.ActiveDocument=App.getDocument("PrinterAssembly") Draft.move([shape],App.Vector(xShift, yShift, zShift),copy=False) App.ActiveDocument.recompute() if shape not in gv.xAxisParts: gv.xAxisParts.append(shape)
def rotateSel(sel, n): p = sel.Object.Placement loc = sel.Object.Placement.Base r = axis.cross(n) # rotation axis a = DraftVecUtils.angle(n, axis, r) * 180 / math.pi PathLog.debug("oh boy: (%.2f, %.2f, %.2f) -> %.2f" % (r.x, r.y, r.z, a)) Draft.rotate(sel.Object, a, axis=r)
def getDataSet(self,obj): "returns a list of objects to be considered by this controller" result = [] if hasattr(obj,"FilterType"): import Draft baseset = FreeCAD.ActiveDocument.Objects if obj.FilterType == "Object Type": for o in baseset: if not ("Spreadsheet" in Draft.getType(o)): t = Draft.getType(o) if t == "Part": t = obj.TypeId if obj.Filter: if obj.Filter in t: result.append(o) else: result.append(o) elif obj.FilterType == "Object Name": for o in baseset: if not ("Spreadsheet" in Draft.getType(o)): if obj.Filter: if obj.Filter in o.Label: result.append(o) else: result.append(o) return result
def setProperties(self,vobj): pl = vobj.PropertiesList if not "Text" in pl: vobj.addProperty("App::PropertyStringList", "Text", "Space",QT_TRANSLATE_NOOP("App::Property","The text to show. Use $area, $label, $tag, $floor, $walls, $ceiling to insert the respective data")) vobj.Text = ["$label","$area"] if not "FontName" in pl: vobj.addProperty("App::PropertyFont", "FontName", "Space",QT_TRANSLATE_NOOP("App::Property","The name of the font")) vobj.FontName = Draft.getParam("textfont","") if not "TextColor" in pl: vobj.addProperty("App::PropertyColor", "TextColor", "Space",QT_TRANSLATE_NOOP("App::Property","The color of the area text")) vobj.TextColor = (0.0,0.0,0.0,1.0) if not "FontSize" in pl: vobj.addProperty("App::PropertyLength", "FontSize", "Space",QT_TRANSLATE_NOOP("App::Property","The size of the text font")) vobj.FontSize = Draft.getParam("textheight",10) if not "FirstLine" in pl: vobj.addProperty("App::PropertyLength", "FirstLine", "Space",QT_TRANSLATE_NOOP("App::Property","The size of the first line of text")) vobj.FirstLine = Draft.getParam("textheight",10) if not "LineSpacing" in pl: vobj.addProperty("App::PropertyFloat", "LineSpacing", "Space",QT_TRANSLATE_NOOP("App::Property","The space between the lines of text")) vobj.LineSpacing = 1.0 if not "TextPosition" in pl: vobj.addProperty("App::PropertyVectorDistance","TextPosition","Space",QT_TRANSLATE_NOOP("App::Property","The position of the text. Leave (0,0,0) for automatic position")) if not "TextAlign" in pl: vobj.addProperty("App::PropertyEnumeration", "TextAlign", "Space",QT_TRANSLATE_NOOP("App::Property","The justification of the text")) vobj.TextAlign = ["Left","Center","Right"] vobj.TextAlign = "Center" if not "Decimals" in pl: vobj.addProperty("App::PropertyInteger", "Decimals", "Space",QT_TRANSLATE_NOOP("App::Property","The number of decimals to use for calculated texts")) vobj.Decimals = Draft.getParam("dimPrecision",2) if not "ShowUnit" in pl: vobj.addProperty("App::PropertyBool", "ShowUnit", "Space",QT_TRANSLATE_NOOP("App::Property","Show the unit suffix")) vobj.ShowUnit = Draft.getParam("showUnit",True)
def getDefaultValues(self,obj): "returns normal,length,width,height values from this component" length = 0 if hasattr(obj,"Length"): if obj.Length.Value: length = obj.Length.Value width = 0 if hasattr(obj,"Width"): if obj.Width.Value: width = obj.Width.Value height = 0 if hasattr(obj,"Height"): if obj.Height.Value: height = obj.Height.Value else: for p in obj.InList: if Draft.getType(p) == "Floor": if p.Height.Value: height = p.Height.Value default = Vector(0,0,1) if Draft.getType(obj) == "Structure": if length > height: default = Vector(1,0,0) if hasattr(obj,"Normal"): if obj.Normal == Vector(0,0,0): normal = default else: normal = Vector(obj.Normal) else: normal = default return normal,length,width,height
def assemble(self): App.ActiveDocument=App.getDocument(self.name) shape = App.ActiveDocument.ActiveObject.Shape App.ActiveDocument=App.getDocument("PrinterAssembly") App.ActiveDocument.addObject('Part::Feature',self.name).Shape= shape #Color Part #Get the feature and move it into position objs = App.ActiveDocument.getObjectsByLabel(self.name) shape = objs[-1] #Rotate into correct orientation # rotateAngle = 0 # rotateCenter = App.Vector(0,0,0) # rotateAxis = App.Vector(1,0,0) # Draft.rotate([shape],rotateAngle,rotateCenter,axis = rotateAxis,copy=False) #Define shifts and move the left clamp into place xShift = +gv.zRodSpacing/2 yShift = gv.extruderNozzleStandoff - gv.zRodStandoff zShift = 0 App.ActiveDocument=App.getDocument("PrinterAssembly") Draft.move([shape],App.Vector(xShift, yShift, zShift),copy=False) App.ActiveDocument.recompute() if shape not in gv.xAxisParts: gv.zAxisParts.append(shape)
def __init__(self,vobj): ArchComponent.ViewProviderComponent.__init__(self,vobj) vobj.Transparency = 85 vobj.LineWidth = 1 vobj.LineColor = (1.0,0.0,0.0,1.0) vobj.DrawStyle = "Dotted" vobj.addProperty("App::PropertyStringList", "Text", "Arch",translate("Arch","The text to show. Use $area, $label, $tag, $floor, $walls, $ceiling to insert the respective data")) vobj.addProperty("App::PropertyString", "FontName", "Arch",translate("Arch","The name of the font")) vobj.addProperty("App::PropertyColor", "TextColor", "Arch",translate("Arch","The color of the area text")) vobj.addProperty("App::PropertyLength", "FontSize", "Arch",translate("Arch","The size of the text font")) vobj.addProperty("App::PropertyLength", "FirstLine", "Arch",translate("Arch","The size of the first line of text")) vobj.addProperty("App::PropertyFloat", "LineSpacing", "Arch",translate("Arch","The space between the lines of text")) vobj.addProperty("App::PropertyVector", "TextPosition","Arch",translate("Arch","The position of the text. Leave (0,0,0) for automatic position")) vobj.addProperty("App::PropertyEnumeration","TextAlign", "Arch",translate("Arch","The justification of the text")) vobj.addProperty("App::PropertyInteger", "Decimals", "Arch",translate("Arch","The number of decimals to use for calculated texts")) vobj.addProperty("App::PropertyBool", "ShowUnit", "Arch",translate("Arch","Show the unit suffix")) vobj.TextColor = (0.0,0.0,0.0,1.0) vobj.Text = ["$label","$area"] vobj.TextAlign = ["Left","Center","Right"] vobj.FontSize = Draft.getParam("textheight",10) vobj.FirstLine = Draft.getParam("textheight",10) vobj.FontName = Draft.getParam("textfont","") vobj.Decimals = Draft.getParam("dimPrecision",2) vobj.ShowUnit = Draft.getParam("showUnit",True) vobj.LineSpacing = 1.0
def removeFromComponent(compobject, subobject): """removeFromComponent(compobject,subobject): subtracts subobject from the given component. If the subobject is already part of the component (as addition, subtraction, etc... it is removed. Otherwise, it is added as a subtraction.""" if compobject == subobject: return found = False attribs = ["Additions", "Subtractions", "Objects", "Components", "Base", "Axes", "Fixtures"] for a in attribs: if hasattr(compobject, a): if a == "Base": if subobject == getattr(compobject, a): setattr(compobject, a, None) subobject.ViewObject.show() found = True else: if subobject in getattr(compobject, a): l = getattr(compobject, a) l.remove(subobject) setattr(compobject, a, l) subobject.ViewObject.show() found = True if not found: if hasattr(compobject, "Subtractions"): l = compobject.Subtractions l.append(subobject) compobject.Subtractions = l if (Draft.getType(subobject) != "Window") and (not Draft.isClone(subobject, "Window", True)): ArchCommands.setAsSubcomponent(subobject)
def execute(self, obj): if hasattr(obj,"Source"): if obj.Source: if not hasattr(self,"svg"): self.onChanged(obj,"Source") else: if not self.svg: self.onChanged(obj,"Source") if not hasattr(self,"svg"): return '' if not hasattr(self,"direction"): p = FreeCAD.Placement(obj.Source.Placement) self.direction = p.Rotation.multVec(FreeCAD.Vector(0,0,1)) linewidth = obj.LineWidth/obj.Scale st = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Arch").GetFloat("CutLineThickness",2) da = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Arch").GetString("archHiddenPattern","30,10") da =da.replace(" ","") svg = self.svg.replace('LWPlaceholder', str(linewidth) + 'px') svg = svg.replace('SWPlaceholder', str(linewidth*st) + 'px') svg = svg.replace('DAPlaceholder', str(da)) if hasattr(self,"spaces"): if round(self.direction.getAngle(FreeCAD.Vector(0,0,1)),Draft.precision()) in [0,round(math.pi,Draft.precision())]: for s in self.spaces: svg += Draft.getSVG(s,scale=obj.Scale,fontsize=obj.FontSize.Value,direction=self.direction) result = '' result += '<g id="' + obj.Name + '"' result += ' transform="' result += 'rotate('+str(obj.Rotation)+','+str(obj.X)+','+str(obj.Y)+') ' result += 'translate('+str(obj.X)+','+str(obj.Y)+') ' result += 'scale('+str(obj.Scale)+','+str(obj.Scale)+')' result += '">\n' result += svg result += '</g>\n' # print "complete node:",result obj.ViewResult = result
def createGeometry(self,obj): import Part pl = obj.Placement if obj.Components: shapes = [] if obj.JoinMode: walls = [] structs = [] for c in obj.Components: if Draft.getType(c) == "Wall": walls.append(c.Shape) elif Draft.getType(c) == "Structure": structs.append(c.Shape) else: shapes.append(c.Shape) for group in [walls,structs]: if group: sh = group.pop(0).copy() for subsh in group: sh = sh.oldFuse(subsh) shapes.append(sh) else: for c in obj.Components: shapes.append(c.Shape) if shapes: obj.Shape = Part.makeCompound(shapes) obj.Placement = pl
def claimChildren(self): if hasattr(self,"Object"): c = [] if hasattr(self.Object,"Base"): if Draft.getType(self.Object) != "Wall": c = [self.Object.Base] elif Draft.getType(self.Object.Base) == "Space": c = [] else: c = [self.Object.Base] if hasattr(self.Object,"Additions"): c.extend(self.Object.Additions) if hasattr(self.Object,"Subtractions"): for s in self.Object.Subtractions: if Draft.getType(self.Object) == "Wall": if Draft.getType(s) == "Roof": continue c.append(s) if hasattr(self.Object,"Armatures"): c.extend(self.Object.Armatures) if hasattr(self.Object,"Group"): c.extend(self.Object.Group) if hasattr(self.Object,"Tool"): if self.Object.Tool: c.append(self.Object.Tool) if hasattr(self.Object,"Subvolume"): if self.Object.Subvolume: c.append(self.Object.Subvolume) return c return []
def execute(self,obj): if obj.Cell and obj.TargetObject and obj.TargetProperty and obj.InList: sp = obj.InList[0] import Draft if Draft.getType(sp) == "Spreadsheet": try: value = getattr(sp.Proxy,obj.Cell) except: if DEBUG: print "No value for cell ",obj.Cell," in spreadsheet." return if obj.TargetType == "Property": b = obj.TargetObject props = obj.TargetProperty.split(".") for p in props: if hasattr(b,p): if p != props[-1]: b = getattr(b,p) else: return try: setattr(b,p,value) if DEBUG: print "setting property ",obj.TargetProperty, " of object ",obj.TargetObject.Name, " to ",value except: if DEBUG: print "unable to set property ",obj.TargetProperty, " of object ",obj.TargetObject.Name, " to ",value else: if Draft.getType(obj.TargetObject) == "Sketch": if obj.TargetProperty.isdigit(): try: c = int(obj.TargetProperty) obj.TargetObject.setDatum(c,float(value)) FreeCAD.ActiveDocument.recompute() if DEBUG: print "setting constraint ",obj.TargetProperty, " of object ",obj.TargetObject.Name, " to ",value except: if DEBUG: print "unable to set constraint ",obj.TargetProperty, " of object ",obj.TargetObject.Name, " to ",value
def run(): e=FreeCADGui.Selection.getSelection()[0] pts=e.Shape.Edge1.Curve.discretize(20) Draft.makeBSpline(pts) FreeCAD.ActiveDocument.ActiveObject.Label="BSpline for " + e.Label e.ViewObject.hide()
def joinWalls(walls): "joins the given list of walls into one sketch-based wall" if not walls: return None if not isinstance(walls,list): walls = [walls] if not areSameWallTypes(walls): return None base = walls.pop() if base.Base: if base.Base.Shape.Faces: return None if Draft.getType(base.Base) == "Sketch": sk = base.Base else: sk = Draft.makeSketch(base.Base,autoconstraints=True) if sk: base.Base = sk for w in walls: if w.Base: if not base.Base.Shape.Faces: for e in base.Base.Shape.Edges: sk.addGeometry(e) FreeCAD.ActiveDocument.recompute() return base
def setProperties(self, vobj): pl = vobj.PropertiesList if not "LineWidth" in pl: vobj.addProperty( "App::PropertyFloat", "LineWidth", "BuildingPart", QT_TRANSLATE_NOOP("App::Property", "The line width of this object")) vobj.LineWidth = 1 if not "OverrideUnit" in pl: vobj.addProperty( "App::PropertyString", "OverrideUnit", "BuildingPart", QT_TRANSLATE_NOOP("App::Property", "An optional unit to express levels")) if not "DisplayOffset" in pl: vobj.addProperty( "App::PropertyPlacement", "DisplayOffset", "BuildingPart", QT_TRANSLATE_NOOP( "App::Property", "A transformation to apply to the level mark")) vobj.DisplayOffset = FreeCAD.Placement( FreeCAD.Vector(0, 0, 0), FreeCAD.Rotation(FreeCAD.Vector(1, 0, 0), 90)) if not "ShowLevel" in pl: vobj.addProperty( "App::PropertyBool", "ShowLevel", "BuildingPart", QT_TRANSLATE_NOOP("App::Property", "If true, show the level")) vobj.ShowLevel = True if not "ShowUnit" in pl: vobj.addProperty( "App::PropertyBool", "ShowUnit", "BuildingPart", QT_TRANSLATE_NOOP("App::Property", "If true, show the unit on the level tag")) if not "SetWorkingPlane" in pl: vobj.addProperty( "App::PropertyBool", "SetWorkingPlane", "BuildingPart", QT_TRANSLATE_NOOP( "App::Property", "If true, when activated, the working plane will automatically adapt to this level" )) vobj.SetWorkingPlane = True if not "OriginOffset" in pl: vobj.addProperty( "App::PropertyBool", "OriginOffset", "BuildingPart", QT_TRANSLATE_NOOP( "App::Property", "If true, when activated, Display offset will affect the origin mark too" )) if not "ShowLabel" in pl: vobj.addProperty( "App::PropertyBool", "ShowLabel", "BuildingPart", QT_TRANSLATE_NOOP( "App::Property", "If true, when activated, the object's label is displayed") ) vobj.ShowLabel = True if not "FontName" in pl: vobj.addProperty( "App::PropertyFont", "FontName", "BuildingPart", QT_TRANSLATE_NOOP("App::Property", "The font to be used for texts")) vobj.FontName = Draft.getParam("textfont", "Arial") if not "FontSize" in pl: vobj.addProperty( "App::PropertyLength", "FontSize", "BuildingPart", QT_TRANSLATE_NOOP("App::Property", "The font size of texts")) vobj.FontSize = Draft.getParam("textheight", 2.0) if not "ViewData" in pl: vobj.addProperty( "App::PropertyFloatList", "ViewData", "BuildingPart", QT_TRANSLATE_NOOP( "App::Property", "Camera position data associated with this object")) if not "RestoreView" in pl: vobj.addProperty( "App::PropertyBool", "RestoreView", "BuildingPart", QT_TRANSLATE_NOOP( "App::Property", "If set, the view stored in this object will be restored on double-click" )) if not "DiffuseColor" in pl: vobj.addProperty( "App::PropertyColorList", "DiffuseColor", "BuildingPart", QT_TRANSLATE_NOOP("App::Property", "The individual face colors")) if not "AutoWorkingPlane" in pl: vobj.addProperty( "App::PropertyBool", "AutoWorkingPlane", "BuildingPart", QT_TRANSLATE_NOOP( "App::Property", "If set to True, the working plane will be kept on Auto mode" ))
def onChanged(self, vobj, prop): if prop == "LineColor": if hasattr(vobj, "LineColor"): l = vobj.LineColor self.mat1.diffuseColor.setValue([l[0], l[1], l[2]]) self.mat2.diffuseColor.setValue([l[0], l[1], l[2]]) elif prop == "Transparency": if hasattr(vobj, "Transparency"): self.mat2.transparency.setValue(vobj.Transparency / 100.0) elif prop in ["DisplayLength", "DisplayHeight", "ArrowSize"]: if hasattr(vobj, "DisplayLength") and hasattr( vobj, "DisplayHeight"): ld = vobj.DisplayLength.Value / 2 hd = vobj.DisplayHeight.Value / 2 elif hasattr(vobj, "DisplaySize"): # old objects ld = vobj.DisplaySize.Value / 2 hd = vobj.DisplaySize.Value / 2 else: ld = 1 hd = 1 verts = [] fverts = [] for v in [[-ld, -hd], [ld, -hd], [ld, hd], [-ld, hd]]: if hasattr(vobj, "ArrowSize"): l1 = vobj.ArrowSize.Value if vobj.ArrowSize.Value > 0 else 0.1 else: l1 = 0.1 l2 = l1 / 3 pl = FreeCAD.Placement(vobj.Object.Placement) p1 = pl.multVec(Vector(v[0], v[1], 0)) p2 = pl.multVec(Vector(v[0], v[1], -l1)) p3 = pl.multVec(Vector(v[0] - l2, v[1], -l1 + l2)) p4 = pl.multVec(Vector(v[0] + l2, v[1], -l1 + l2)) p5 = pl.multVec(Vector(v[0], v[1] - l2, -l1 + l2)) p6 = pl.multVec(Vector(v[0], v[1] + l2, -l1 + l2)) verts.extend([[p1.x, p1.y, p1.z], [p2.x, p2.y, p2.z]]) fverts.append([p1.x, p1.y, p1.z]) verts.extend([[p2.x, p2.y, p2.z], [p3.x, p3.y, p3.z], [p4.x, p4.y, p4.z], [p2.x, p2.y, p2.z]]) verts.extend([[p2.x, p2.y, p2.z], [p5.x, p5.y, p5.z], [p6.x, p6.y, p6.z], [p2.x, p2.y, p2.z]]) verts.extend(fverts + [fverts[0]]) self.lcoords.point.setValues(verts) self.fcoords.point.setValues(fverts) elif prop == "LineWidth": self.drawstyle.lineWidth = vobj.LineWidth elif prop in ["CutView", "CutMargin"]: if hasattr(vobj, "CutView") and FreeCADGui.ActiveDocument.ActiveView: sg = FreeCADGui.ActiveDocument.ActiveView.getSceneGraph() if vobj.CutView: if self.clip: sg.removeChild(self.clip) self.clip = None for o in Draft.getGroupContents(vobj.Object.Objects, walls=True): if hasattr(o.ViewObject, "Lighting"): o.ViewObject.Lighting = "One side" self.clip = coin.SoClipPlane() self.clip.on.setValue(True) norm = vobj.Object.Proxy.getNormal(vobj.Object) mp = vobj.Object.Shape.CenterOfMass mp = DraftVecUtils.project(mp, norm) dist = mp.Length #- 0.1 # to not clip exactly on the section object norm = norm.negative() marg = 1 if hasattr(vobj, "CutMargin"): marg = vobj.CutMargin.Value if mp.getAngle(norm) > 1: dist += marg dist = -dist else: dist -= marg plane = coin.SbPlane(coin.SbVec3f(norm.x, norm.y, norm.z), dist) self.clip.plane.setValue(plane) sg.insertChild(self.clip, 0) else: if self.clip: sg.removeChild(self.clip) self.clip = None return
def processSubShapes(obj, base, placement=None): "Adds additions and subtractions to a base shape" #print("processSubShapes Start") import Draft, Part if placement: if placement.isNull(): placement = None else: placement = FreeCAD.Placement(placement) placement = placement.inverse() # treat additions for o in obj.Additions: if not base: if o.isDerivedFrom("Part::Feature"): base = o.Shape else: if base.isNull(): if o.isDerivedFrom("Part::Feature"): base = o.Shape else: # special case, both walls with coinciding endpoints import ArchWall js = ArchWall.mergeShapes(o, obj) if js: add = js.cut(base) if placement: add.Placement = add.Placement.multiply(placement) base = base.fuse(add) elif (Draft.getType(o) == "Window") or (Draft.isClone( o, "Window", True)): f = o.Proxy.getSubVolume(o) if f: if base.Solids and f.Solids: if placement: f.Placement = f.Placement.multiply(placement) base = base.cut(f) elif o.isDerivedFrom("Part::Feature"): if o.Shape: if not o.Shape.isNull(): if o.Shape.Solids: s = o.Shape.copy() if placement: s.Placement = s.Placement.multiply( placement) if base: if base.Solids: try: base.Placement = FreeCAD.Placement( ) base = base.fuse(s) except Part.OCCError: print "Arch: unable to fuse object ", obj.Name, " with ", o.Name else: base = s # treat subtractions for o in obj.Subtractions: if base: if base.isNull(): base = None if base: if (Draft.getType(o) == "Window") or (Draft.isClone( o, "Window", True)): # windows can be additions or subtractions, treated the same way f = o.Proxy.getSubVolume(o) if f: if base.Solids and f.Solids: if placement: f.Placement = f.Placement.multiply(placement) base = base.cut(f) elif (Draft.getType(o) == "Roof") or (Draft.isClone(o, "Roof")): # roofs define their own special subtraction volume f = o.Proxy.getSubVolume(o) if f: if base.Solids and f.Solids: base = base.cut(f) elif o.isDerivedFrom("Part::Feature"): if o.Shape: if not o.Shape.isNull(): if o.Shape.Solids and base.Solids: s = o.Shape.copy() if placement: s.Placement = s.Placement.multiply(placement) try: base.Placement = FreeCAD.Placement() base = base.cut(s) except Part.OCCError: print "Arch: unable to cut object ", o.Name, " from ", obj.Name #print("processSubShapes End") return base
def __init__(self): # self.space = 1 self.space = Draft.getParam("gridSpacing", 1) # self.mainlines = 10 self.mainlines = Draft.getParam("gridEvery", 10) self.numlines = 100 col = [0.2, 0.2, 0.3] pick = coin.SoPickStyle() pick.style.setValue(coin.SoPickStyle.UNPICKABLE) self.trans = coin.SoTransform() self.trans.translation.setValue([0, 0, 0]) bound = (self.numlines / 2) * self.space pts = [] mpts = [] apts = [] for i in range(self.numlines + 1): curr = -bound + i * self.space z = 0 if i / float(self.mainlines) == i / self.mainlines: if round(curr, 4) == 0: apts.extend([[-bound, curr, z], [bound, curr, z]]) apts.extend([[curr, -bound, z], [curr, bound, z]]) else: mpts.extend([[-bound, curr, z], [bound, curr, z]]) mpts.extend([[curr, -bound, z], [curr, bound, z]]) else: pts.extend([[-bound, curr, z], [bound, curr, z]]) pts.extend([[curr, -bound, z], [curr, bound, z]]) idx = [] midx = [] aidx = [] for p in range(0, len(pts), 2): idx.append(2) for mp in range(0, len(mpts), 2): midx.append(2) for ap in range(0, len(apts), 2): aidx.append(2) mat1 = coin.SoMaterial() mat1.transparency.setValue(0.7) mat1.diffuseColor.setValue(col) self.coords1 = coin.SoCoordinate3() self.coords1.point.setValues(pts) lines1 = coin.SoLineSet() lines1.numVertices.setValues(idx) mat2 = coin.SoMaterial() mat2.transparency.setValue(0.3) mat2.diffuseColor.setValue(col) self.coords2 = coin.SoCoordinate3() self.coords2.point.setValues(mpts) lines2 = coin.SoLineSet() lines2.numVertices.setValues(midx) mat3 = coin.SoMaterial() mat3.transparency.setValue(0) mat3.diffuseColor.setValue(col) self.coords3 = coin.SoCoordinate3() self.coords3.point.setValues(apts) lines3 = coin.SoLineSet() lines3.numVertices.setValues(aidx) s = coin.SoSeparator() s.addChild(pick) s.addChild(self.trans) s.addChild(mat1) s.addChild(self.coords1) s.addChild(lines1) s.addChild(mat2) s.addChild(self.coords2) s.addChild(lines2) s.addChild(mat3) s.addChild(self.coords3) s.addChild(lines3) Tracker.__init__(self, children=[s]) self.update()
def accept(self): if self.form.groupNewDocument.isChecked() or (FreeCAD.ActiveDocument is None): doc = FreeCAD.newDocument() if self.form.projectName.text(): doc.Label = self.form.projectName.text() FreeCAD.ActiveDocument = doc if not FreeCAD.ActiveDocument: FreeCAD.Console.PrintError(translate("BIM","No active document, aborting.")+"\n") import Draft,Arch,Part site = None outline = None if self.form.groupSite.isChecked(): site = Arch.makeSite() site.Label = self.form.siteName.text() site.Address = self.form.siteAddress.text() site.Longitude = self.form.siteLongitude.value() site.Latitude = self.form.siteLatitude.value() if hasattr(site,"NorthDeviation"): site.NorthDeviation = self.form.siteDeviation.value() elif hasattr(site,"Declination"): site.Declination = self.form.siteDeviation.value() site.Elevation = FreeCAD.Units.Quantity(self.form.siteElevation.text()).Value human = None if self.form.addHumanFigure.isChecked(): humanshape = Part.Shape() humanpath = os.path.join(os.path.dirname(__file__),"geometry","human figure.brep") humanshape.importBrep(humanpath) human = FreeCAD.ActiveDocument.addObject("Part::Feature","Human") human.Shape = humanshape human.Placement.move(FreeCAD.Vector(500,500,0)) if self.form.groupBuilding.isChecked(): building = Arch.makeBuilding() if site: site.Group = [building] building.Label = self.form.buildingName.text() building.BuildingType = self.form.buildingUse.currentText() buildingWidth = FreeCAD.Units.Quantity(self.form.buildingWidth.text()).Value buildingLength = FreeCAD.Units.Quantity(self.form.buildingLength.text()).Value distVAxes = FreeCAD.Units.Quantity(self.form.distVAxes.text()).Value distHAxes = FreeCAD.Units.Quantity(self.form.distHAxes.text()).Value levelHeight = FreeCAD.Units.Quantity(self.form.levelHeight.text()).Value color = self.form.lineColor.property("color").getRgbF()[:3] if buildingWidth and buildingLength: outline = Draft.makeRectangle(buildingLength,buildingWidth,face=False) outline.Label = translate("BIM","Building Outline") outline.ViewObject.DrawStyle = "Dashed" outline.ViewObject.LineColor = color outline.ViewObject.LineWidth = self.form.lineWidth.value()*2 grp = FreeCAD.ActiveDocument.addObject("App::DocumentObjectGroup") grp.Label = translate("BIM","Building Layout") building.addObject(grp) grp.addObject(outline) if self.form.buildingName.text(): outtext = Draft.makeText([self.form.buildingName.text()],point=FreeCAD.Vector(Draft.getParam("textheight",0.20)*0.3,-Draft.getParam("textheight",0.20)*1.43,0)) outtext.Label = translate("BIM","Building Label") outtext.ViewObject.TextColor = color grp.addObject(outtext) if human: grp.addObject(human) axisV = None if self.form.countVAxes.value() and distVAxes: axisV = Arch.makeAxis(num = self.form.countVAxes.value(), size = distVAxes, name="vaxis") axisV.Label = translate("BIM","Vertical Axes") axisV.ViewObject.BubblePosition = "Both" axisV.ViewObject.LineWidth = self.form.lineWidth.value() axisV.ViewObject.FontSize = Draft.getParam("textheight",0.20) axisV.ViewObject.BubbleSize = Draft.getParam("textheight",0.20)*1.43 axisV.ViewObject.LineColor = color if outline: axisV.setExpression('Length', outline.Name+'.Height * 1.1') axisV.setExpression('Placement.Base.y', outline.Name+'.Placement.Base.y - '+axisV.Name+'.Length * 0.05') axisV.setExpression('Placement.Base.x', outline.Name+'.Placement.Base.x') axisH = None if self.form.countHAxes.value() and distHAxes: axisH = Arch.makeAxis(num = self.form.countHAxes.value(), size = distHAxes, name="haxis") axisH.Label = translate("BIM","Horizontal Axes") axisH.ViewObject.BubblePosition = "Both" axisH.ViewObject.NumberingStyle = "A,B,C" axisH.ViewObject.LineWidth = self.form.lineWidth.value() axisH.ViewObject.FontSize = Draft.getParam("textheight",0.20) axisH.ViewObject.BubbleSize = Draft.getParam("textheight",0.20)*1.43 axisH.Placement.Rotation = FreeCAD.Rotation(FreeCAD.Vector(0,0,1),90) axisH.ViewObject.LineColor = color if outline: axisH.setExpression('Length', outline.Name+'.Length * 1.1') axisH.setExpression('Placement.Base.x', outline.Name+'.Placement.Base.x + '+axisH.Name+'.Length * 0.945') axisH.setExpression('Placement.Base.y', outline.Name+'.Placement.Base.y') if axisV and axisH: axisG = Arch.makeAxisSystem([axisH,axisV]) axisG.Label = translate("BIM","Axes") grp.addObject(axisG) else: if axisV: grp.addObject(axisV) if axisH: grp.addObject(axisH) if self.form.countLevels.value() and levelHeight: h = 0 alabels = [] for i in range(self.form.countLevels.value()): lev = Arch.makeFloor() lev.Label = translate("BIM","Level")+" "+str(i) alabels.append(lev.Label) lev.Height = levelHeight lev.Placement.move(FreeCAD.Vector(0,0,h)) h += levelHeight building.addObject(lev) if self.form.levelsWP.isChecked(): prx = Draft.makeWorkingPlaneProxy(FreeCAD.Placement()) prx.Placement.move(FreeCAD.Vector(0,0,h)) lev.addObject(prx) if self.form.levelsAxis.isChecked(): axisL = Arch.makeAxis(num = self.form.countLevels.value(), size = levelHeight, name="laxis") axisL.Label = translate("BIM","Level Axes") axisL.ViewObject.BubblePosition = "None" axisL.ViewObject.LineWidth = self.form.lineWidth.value() axisL.ViewObject.FontSize = Draft.getParam("textheight",0.20) axisL.Placement.Rotation = FreeCAD.Rotation(FreeCAD.Vector (0.577350269189626, -0.5773502691896257, 0.5773502691896257),120) axisL.ViewObject.LineColor = color axisL.ViewObject.LabelOffset.Rotation = FreeCAD.Rotation(FreeCAD.Vector(1,0,0),90) axisL.Labels = alabels axisL.ViewObject.ShowLabel = True if outline: axisL.setExpression('Length', outline.Name+'.Length * 1.1') axisL.setExpression('Placement.Base.x', outline.Name+'.Placement.Base.x + '+axisL.Name+'.Length * 0.945') axisL.setExpression('Placement.Base.y', outline.Name+'.Placement.Base.y') grp.addObject(axisL) axisL.ViewObject.LabelOffset.Base = FreeCAD.Vector(-axisL.Length.Value + Draft.getParam("textheight",0.20)*0.43,0,Draft.getParam("textheight",0.20)*0.43) self.form.hide() FreeCAD.ActiveDocument.recompute() if outline: FreeCADGui.Selection.clearSelection() FreeCADGui.Selection.addSelection(outline) FreeCADGui.SendMsgToActiveView("ViewSelection") FreeCADGui.Selection.clearSelection() if hasattr(FreeCADGui,"Snapper"): FreeCADGui.Snapper.show() return True
def _removeSwitch(self, switch): '''remove self.switch from the scene graph. As with _insertSwitch, must not be called during scene graph traversal).''' sg = Draft.get3DView().getSceneGraph() sg.removeChild(switch)
def update(self, index=None): "updates the tree widgets in all tabs" import Draft # quantities tab - only fill once if not self.quantitiesDrawn: self.qmodel.setHorizontalHeaderLabels( translate("BIM", ["Label"]) + trqprops) quantheaders = self.form.quantities.header() #QHeaderView instance if hasattr(quantheaders, "setClickable"): # qt4 quantheaders.setClickable(True) else: # qt5 quantheaders.setSectionsClickable(True) quantheaders.sectionClicked.connect(self.quantHeaderClicked) # sort by type groups = {} for name, role in self.objectslist.items(): groups.setdefault(role, []).append(name) for names in groups.values(): for name in names: obj = FreeCAD.ActiveDocument.getObject(name) if obj: if (not self.form.onlyVisible.isChecked() ) or obj.ViewObject.isVisible(): if obj.isDerivedFrom("Part::Feature") and not ( Draft.getType(obj) == "Site"): it1 = QtGui.QStandardItem(obj.Label) it1.setToolTip(name) it1.setEditable(False) if QtCore.QFileInfo(":/icons/Arch_" + obj.Proxy.Type + "_Tree.svg").exists(): icon = QtGui.QIcon(":/icons/Arch_" + obj.Proxy.Type + "_Tree.svg") else: icon = QtGui.QIcon( ":/icons/Arch_Component.svg") it1.setIcon(icon) props = [] for prop in qprops: it = QtGui.QStandardItem() val = None if prop == "Volume": if obj.Shape and hasattr( obj.Shape, "Volume"): val = FreeCAD.Units.Quantity( obj.Shape.Volume, FreeCAD.Units.Volume) it.setText(val.getUserPreferred() [0].replace( u"^3", u"³")) it.setCheckable(True) else: if hasattr(obj, prop) and ( not "Hidden" in obj.getEditorMode(prop)): val = getattr(obj, prop) it.setText(val.getUserPreferred() [0].replace( u"^2", u"²")) it.setCheckable(True) if val != None: if hasattr(obj, "IfcAttributes") and ( "Export" + prop in obj.IfcAttributes ) and (obj.IfcAttributes["Export" + prop] == "True"): it.setCheckState(QtCore.Qt.Checked) if val == 0: it.setIcon( QtGui.QIcon( os.path.join( os.path.dirname( __file__), "icons", "warning.svg"))) if prop in [ "Area", "HorizontalArea", "VerticalArea", "Volume" ]: it.setEditable(False) props.append(it) self.qmodel.appendRow([it1] + props) self.quantitiesDrawn = True
def onChanged(self, vobj, prop): #print(vobj.Object.Label," - ",prop) if prop == "ShapeColor": if hasattr(vobj, "ShapeColor"): l = vobj.ShapeColor self.mat.diffuseColor.setValue([l[0], l[1], l[2]]) elif prop == "LineWidth": if hasattr(vobj, "LineWidth"): self.dst.lineWidth = vobj.LineWidth elif prop == "FontName": if hasattr(vobj, "FontName"): if vobj.FontName: if sys.version_info.major < 3: self.fon.name = vobj.FontName.encode("utf8") else: self.fon.name = vobj.FontName elif prop in ["FontSize", "DisplayOffset", "OriginOffset"]: if hasattr(vobj, "FontSize") and hasattr( vobj, "DisplayOffset") and hasattr(vobj, "OriginOffset"): fs = vobj.FontSize.Value if fs: self.fon.size = fs b = vobj.DisplayOffset.Base self.tra.translation.setValue( [b.x + fs / 8, b.y, b.z + fs / 8]) r = vobj.DisplayOffset.Rotation self.tra.rotation.setValue(r.Q) if vobj.OriginOffset: self.lco.point.setValues([[b.x - fs, b.y, b.z], [b.x + fs, b.y, b.z], [b.x, b.y - fs, b.z], [b.x, b.y + fs, b.z], [b.x, b.y, b.z - fs], [b.x, b.y, b.z + fs]]) else: self.lco.point.setValues([[-fs, 0, 0], [fs, 0, 0], [0, -fs, 0], [0, fs, 0], [0, 0, -fs], [0, 0, fs]]) elif prop in ["OverrideUnit", "ShowUnit", "ShowLevel", "ShowLabel"]: if hasattr(vobj, "OverrideUnit") and hasattr( vobj, "ShowUnit") and hasattr( vobj, "ShowLevel") and hasattr(vobj, "ShowLabel"): z = vobj.Object.Placement.Base.z + vobj.Object.LevelOffset.Value q = FreeCAD.Units.Quantity(z, FreeCAD.Units.Length) txt = "" if vobj.ShowLabel: txt += vobj.Object.Label if vobj.ShowLevel: if txt: txt += " " if z >= 0: txt += "+" if vobj.OverrideUnit: u = vobj.OverrideUnit else: u = q.getUserPreferred()[2] try: q = q.getValueAs(u) except Exception: q = q.getValueAs(q.getUserPreferred()[2]) d = FreeCAD.ParamGet( "User parameter:BaseApp/Preferences/Units").GetInt( "Decimals", 0) fmt = "{0:." + str(d) + "f}" if not vobj.ShowUnit: u = "" txt += fmt.format(float(q)) + str(u) if not txt: txt = " " # empty texts make coin crash... if isinstance(txt, unicode): txt = txt.encode("utf8") self.txt.string.setValue(txt) elif prop in [ "ChildrenOverride", "ChildenLineWidth", "ChildrenLineColor", "ChildrenShapeColor", "ChildrenTransparency" ]: if hasattr(vobj, "ChildrenOverride") and vobj.ChildrenOverride: props = [ "ChildenLineWidth", "ChildrenLineColor", "ChildrenShapeColor", "ChildrenTransparency" ] for child in vobj.Object.Group: for prop in props: if hasattr(vobj, prop) and hasattr( child.ViewObject, prop[8:]) and not hasattr( child, "ChildrenOverride"): setattr(child.ViewObject, prop[8:], getattr(vobj, prop)) elif prop in ["CutView", "CutMargin"]: if hasattr(vobj, "CutView") and FreeCADGui.ActiveDocument.ActiveView: sg = FreeCADGui.ActiveDocument.ActiveView.getSceneGraph() if vobj.CutView: from pivy import coin if self.clip: sg.removeChild(self.clip) self.clip = None for o in Draft.get_group_contents(vobj.Object.Group, walls=True): if hasattr(o.ViewObject, "Lighting"): o.ViewObject.Lighting = "One side" self.clip = coin.SoClipPlane() self.clip.on.setValue(True) norm = vobj.Object.Placement.multVec( FreeCAD.Vector(0, 0, 1)) mp = vobj.Object.Placement.Base mp = DraftVecUtils.project(mp, norm) dist = mp.Length #- 0.1 # to not clip exactly on the section object norm = norm.negative() marg = 1 if hasattr(vobj, "CutMargin"): marg = vobj.CutMargin.Value if mp.getAngle(norm) > 1: dist += marg dist = -dist else: dist -= marg plane = coin.SbPlane(coin.SbVec3f(norm.x, norm.y, norm.z), dist) self.clip.plane.setValue(plane) sg.insertChild(self.clip, 0) else: if self.clip: sg.removeChild(self.clip) self.clip = None for o in Draft.get_group_contents(vobj.Object.Group, walls=True): if hasattr(o.ViewObject, "Lighting"): o.ViewObject.Lighting = "Two side" elif prop == "Visibility": # turn clipping off when turning the object off if hasattr(vobj, "Visibility") and not (vobj.Visibility) and hasattr( vobj, "CutView"): vobj.CutView = False elif prop == "SaveInventor": self.writeInventor(vobj.Object)
def setProperties(self, vobj): pl = vobj.PropertiesList if not "LineWidth" in pl: vobj.addProperty( "App::PropertyFloat", "LineWidth", "BuildingPart", QT_TRANSLATE_NOOP("App::Property", "The line width of this object")) vobj.LineWidth = 1 if not "OverrideUnit" in pl: vobj.addProperty( "App::PropertyString", "OverrideUnit", "BuildingPart", QT_TRANSLATE_NOOP("App::Property", "An optional unit to express levels")) if not "DisplayOffset" in pl: vobj.addProperty( "App::PropertyPlacement", "DisplayOffset", "BuildingPart", QT_TRANSLATE_NOOP( "App::Property", "A transformation to apply to the level mark")) vobj.DisplayOffset = FreeCAD.Placement( FreeCAD.Vector(0, 0, 0), FreeCAD.Rotation(FreeCAD.Vector(1, 0, 0), 90)) if not "ShowLevel" in pl: vobj.addProperty( "App::PropertyBool", "ShowLevel", "BuildingPart", QT_TRANSLATE_NOOP("App::Property", "If true, show the level")) vobj.ShowLevel = True if not "ShowUnit" in pl: vobj.addProperty( "App::PropertyBool", "ShowUnit", "BuildingPart", QT_TRANSLATE_NOOP("App::Property", "If true, show the unit on the level tag")) if not "OriginOffset" in pl: vobj.addProperty( "App::PropertyBool", "OriginOffset", "BuildingPart", QT_TRANSLATE_NOOP( "App::Property", "If true, display offset will affect the origin mark too")) if not "ShowLabel" in pl: vobj.addProperty( "App::PropertyBool", "ShowLabel", "BuildingPart", QT_TRANSLATE_NOOP("App::Property", "If true, the object's label is displayed")) vobj.ShowLabel = True if not "FontName" in pl: vobj.addProperty( "App::PropertyFont", "FontName", "BuildingPart", QT_TRANSLATE_NOOP("App::Property", "The font to be used for texts")) vobj.FontName = Draft.getParam("textfont", "Arial") if not "FontSize" in pl: vobj.addProperty( "App::PropertyLength", "FontSize", "BuildingPart", QT_TRANSLATE_NOOP("App::Property", "The font size of texts")) vobj.FontSize = Draft.getParam("textheight", 2.0) if not "DiffuseColor" in pl: vobj.addProperty( "App::PropertyColorList", "DiffuseColor", "BuildingPart", QT_TRANSLATE_NOOP("App::Property", "The individual face colors")) # Interaction properties if not "SetWorkingPlane" in pl: vobj.addProperty( "App::PropertyBool", "SetWorkingPlane", "Interaction", QT_TRANSLATE_NOOP( "App::Property", "If true, when activated, the working plane will automatically adapt to this level" )) vobj.SetWorkingPlane = True if not "AutoWorkingPlane" in pl: vobj.addProperty( "App::PropertyBool", "AutoWorkingPlane", "Interaction", QT_TRANSLATE_NOOP( "App::Property", "If set to True, the working plane will be kept on Auto mode" )) if not "ViewData" in pl: vobj.addProperty( "App::PropertyFloatList", "ViewData", "Interaction", QT_TRANSLATE_NOOP( "App::Property", "Camera position data associated with this object")) vobj.setEditorMode("ViewData", 2) if not "RestoreView" in pl: vobj.addProperty( "App::PropertyBool", "RestoreView", "Interaction", QT_TRANSLATE_NOOP( "App::Property", "If set, the view stored in this object will be restored on double-click" )) if not "DoubleClickActivates" in pl: vobj.addProperty( "App::PropertyBool", "DoubleClickActivates", "Interaction", QT_TRANSLATE_NOOP( "App::Property", "If True, double-clicking this object in the tree activates it" )) # inventor saving if not "SaveInventor" in pl: vobj.addProperty( "App::PropertyBool", "SaveInventor", "Interaction", QT_TRANSLATE_NOOP( "App::Property", "If this is enabled, the inventor representation of this object will be saved in the FreeCAD file, allowing to reference it in other files in lightweight mode." )) if not "SavedInventor" in pl: vobj.addProperty( "App::PropertyFileIncluded", "SavedInventor", "Interaction", QT_TRANSLATE_NOOP( "App::Property", "A slot to save the inventor representation of this object, if enabled" )) vobj.setEditorMode("SavedInventor", 2) # children properties if not "ChildrenOverride" in pl: vobj.addProperty( "App::PropertyBool", "ChildrenOverride", "Children", QT_TRANSLATE_NOOP( "App::Property", "If true, show the objects contained in this Building Part will adopt these line, color and transparency settings" )) if not "ChildrenLineWidth" in pl: vobj.addProperty( "App::PropertyFloat", "ChildrenLineWidth", "Children", QT_TRANSLATE_NOOP("App::Property", "The line width of child objects")) vobj.LineWidth = 1 if not "ChildrenLineColor" in pl: vobj.addProperty( "App::PropertyColor", "ChildrenLineColor", "Children", QT_TRANSLATE_NOOP("App::Property", "The line color of child objects")) c = FreeCAD.ParamGet( "User parameter:BaseApp/Preferences/View").GetUnsigned( "DefaultShapeLineColor", 255) vobj.ChildrenLineColor = (float((c >> 24) & 0xFF) / 255.0, float((c >> 16) & 0xFF) / 255.0, float((c >> 8) & 0xFF) / 255.0, 0.0) if not "ChildrenShapeolor" in pl: vobj.addProperty( "App::PropertyColor", "ChildrenShapeColor", "Children", QT_TRANSLATE_NOOP("App::Property", "The shape color of child objects")) c = FreeCAD.ParamGet( "User parameter:BaseApp/Preferences/View").GetUnsigned( "DefaultShapeColor", 4294967295) vobj.ChildrenLineColor = (float((c >> 24) & 0xFF) / 255.0, float((c >> 16) & 0xFF) / 255.0, float((c >> 8) & 0xFF) / 255.0, 0.0) if not "ChildrenTransparency" in pl: vobj.addProperty( "App::PropertyPercent", "ChildrenTransparency", "Children", QT_TRANSLATE_NOOP("App::Property", "The transparency of child objects")) # clip properties if not "CutView" in pl: vobj.addProperty( "App::PropertyBool", "CutView", "Clip", QT_TRANSLATE_NOOP("App::Property", "Cut the view above this level")) if not "CutMargin" in pl: vobj.addProperty( "App::PropertyLength", "CutMargin", "Clip", QT_TRANSLATE_NOOP( "App::Property", "The distance between the level plane and the cut line")) vobj.CutMargin = 1600 if not "AutoCutView" in pl: vobj.addProperty( "App::PropertyBool", "AutoCutView", "Clip", QT_TRANSLATE_NOOP( "App::Property", "Turn cutting on when activating this level"))
def makeStraightStairs(self, obj, edge, numberofsteps=None): "builds a simple, straight staircase from a straight edge" # Upgrade obj if it is from an older version of FreeCAD if not (hasattr(obj, "StringerOverlap")): obj.addProperty( "App::PropertyLength", "StringerOverlap", "Structure", QT_TRANSLATE_NOOP( "App::Property", "The overlap of the stringers above the bottom of the treads" )) # general data import Part, DraftGeomUtils if not numberofsteps: numberofsteps = obj.NumberOfSteps v = DraftGeomUtils.vec(edge) vLength = DraftVecUtils.scaleTo( v, float(edge.Length) / (numberofsteps - 1)) vLength = Vector(vLength.x, vLength.y, 0) if round(v.z, Draft.precision()) != 0: h = v.z else: h = obj.Height.Value vHeight = Vector(0, 0, float(h) / numberofsteps) vWidth = DraftVecUtils.scaleTo(vLength.cross(Vector(0, 0, 1)), obj.Width.Value) vBase = edge.Vertexes[0].Point vNose = DraftVecUtils.scaleTo(vLength, -abs(obj.Nosing.Value)) a = math.atan(vHeight.Length / vLength.Length) #print("stair data:",vLength.Length,":",vHeight.Length) # steps for i in range(numberofsteps - 1): p1 = vBase.add((Vector(vLength).multiply(i)).add( Vector(vHeight).multiply(i + 1))) p1 = self.align(p1, obj.Align, vWidth) p1 = p1.add(vNose).add(Vector(0, 0, -abs(obj.TreadThickness.Value))) p2 = p1.add(DraftVecUtils.neg(vNose)).add(vLength) p3 = p2.add(vWidth) p4 = p3.add(DraftVecUtils.neg(vLength)).add(vNose) step = Part.Face(Part.makePolygon([p1, p2, p3, p4, p1])) if obj.TreadThickness.Value: step = step.extrude(Vector(0, 0, abs(obj.TreadThickness.Value))) self.steps.append(step) else: self.pseudosteps.append(step) # structure lProfile = [] struct = None if obj.Structure == "Massive": if obj.StructureThickness.Value: for i in range(numberofsteps - 1): if not lProfile: lProfile.append(vBase) last = lProfile[-1] if len(lProfile) == 1: last = last.add( Vector(0, 0, -abs(obj.TreadThickness.Value))) lProfile.append(last.add(vHeight)) lProfile.append(lProfile[-1].add(vLength)) resHeight1 = obj.StructureThickness.Value / math.cos(a) lProfile.append(lProfile[-1].add(Vector(0, 0, -resHeight1))) resHeight2 = ((numberofsteps - 1) * vHeight.Length) - ( resHeight1 + obj.TreadThickness.Value) resLength = (vLength.Length / vHeight.Length) * resHeight2 h = DraftVecUtils.scaleTo(vLength, -resLength) lProfile.append(lProfile[-1].add(Vector(h.x, h.y, -resHeight2))) lProfile.append(vBase) #print(lProfile) pol = Part.makePolygon(lProfile) struct = Part.Face(pol) evec = vWidth if obj.StructureOffset.Value: mvec = DraftVecUtils.scaleTo(vWidth, obj.StructureOffset.Value) struct.translate(mvec) evec = DraftVecUtils.scaleTo( evec, evec.Length - (2 * mvec.Length)) struct = struct.extrude(evec) elif obj.Structure in ["One stringer", "Two stringers"]: if obj.StringerWidth.Value and obj.StructureThickness.Value: hyp = math.sqrt(vHeight.Length**2 + vLength.Length**2) l1 = Vector(vLength).multiply(numberofsteps - 1) h1 = Vector(vHeight).multiply(numberofsteps - 1).add( Vector( 0, 0, -abs(obj.TreadThickness.Value) + obj.StringerOverlap.Value)) p1 = vBase.add(l1).add(h1) p1 = self.align(p1, obj.Align, vWidth) if obj.StringerOverlap.Value <= float(h) / numberofsteps: lProfile.append(p1) else: p1b = vBase.add(l1).add(Vector(0, 0, float(h))) p1a = p1b.add( Vector(vLength).multiply( (p1b.z - p1.z) / vHeight.Length)) lProfile.append(p1a) lProfile.append(p1b) h2 = (obj.StructureThickness.Value / vLength.Length) * hyp lProfile.append(p1.add(Vector(0, 0, -abs(h2)))) h3 = lProfile[-1].z - vBase.z l3 = (h3 / vHeight.Length) * vLength.Length v3 = DraftVecUtils.scaleTo(vLength, -l3) lProfile.append(lProfile[-1].add(Vector(0, 0, -abs(h3))).add(v3)) l4 = (obj.StructureThickness.Value / vHeight.Length) * hyp v4 = DraftVecUtils.scaleTo(vLength, -l4) lProfile.append(lProfile[-1].add(v4)) lProfile.append(lProfile[0]) #print(lProfile) pol = Part.makePolygon(lProfile) pol = Part.Face(pol) evec = DraftVecUtils.scaleTo(vWidth, obj.StringerWidth.Value) if obj.Structure == "One stringer": if obj.StructureOffset.Value: mvec = DraftVecUtils.scaleTo(vWidth, obj.StructureOffset.Value) else: mvec = DraftVecUtils.scaleTo( vWidth, (vWidth.Length / 2) - obj.StringerWidth.Value / 2) pol.translate(mvec) struct = pol.extrude(evec) elif obj.Structure == "Two stringers": pol2 = pol.copy() if obj.StructureOffset.Value: mvec = DraftVecUtils.scaleTo(vWidth, obj.StructureOffset.Value) pol.translate(mvec) mvec = vWidth.add(mvec.negative()) pol2.translate(mvec) else: pol2.translate(vWidth) s1 = pol.extrude(evec) s2 = pol2.extrude(evec.negative()) struct = Part.makeCompound([s1, s2]) if struct: self.structures.append(struct)
def saveSnapModes(self): "saves the snap modes for next sessions" t = '' for b in [self.masterbutton]+self.toolbarButtons: t += str(int(b.isChecked())) Draft.setParam("snapModes",t)
def showradius(self): "shows the snap radius indicator" self.radius = self.getScreenDist(Draft.getParam("snapRange"),(400,300)) if self.radiusTracker: self.radiusTracker.update(self.radius) self.radiusTracker.on()
def getScreenDist(self,dist,cursor): "returns a distance in 3D space from a screen pixels distance" view = Draft.get3DView() p1 = view.getPoint(cursor) p2 = view.getPoint((cursor[0]+dist,cursor[1])) return (p2.sub(p1)).Length
def getPoint(self,last=None,callback=None,movecallback=None,extradlg=None): """ getPoint([last],[callback],[movecallback],[extradlg]) : gets a 3D point from the screen. You can provide an existing point, in that case additional snap options and a tracker are available. You can also pass a function as callback, which will get called with the resulting point as argument, when a point is clicked, and optionally another callback which gets called when the mouse is moved. If the operation gets cancelled (the user pressed Escape), no point is returned. Example: def cb(point): if point: print "got a 3D point: ",point FreeCADGui.Snapper.getPoint(callback=cb) If the callback function accepts more than one argument, it will also receive the last snapped object. Finally, a pyqt dialog can be passed as extra taskbox. """ import inspect self.pt = None self.lastSnappedObject = None self.ui = FreeCADGui.draftToolBar self.view = Draft.get3DView() def move(event_cb): event = event_cb.getEvent() mousepos = event.getPosition() ctrl = event.wasCtrlDown() shift = event.wasShiftDown() self.pt = FreeCADGui.Snapper.snap(mousepos,lastpoint=last,active=ctrl,constrain=shift) if hasattr(FreeCAD,"DraftWorkingPlane"): self.ui.displayPoint(self.pt,last,plane=FreeCAD.DraftWorkingPlane,mask=FreeCADGui.Snapper.affinity) if movecallback: movecallback(self.pt) def getcoords(point,relative=False): self.pt = point if relative and last and hasattr(FreeCAD,"DraftWorkingPlane"): v = FreeCAD.DraftWorkingPlane.getGlobalCoords(point) self.pt = last.add(v) accept() def click(event_cb): event = event_cb.getEvent() if event.getButton() == 1: if event.getState() == coin.SoMouseButtonEvent.DOWN: accept() def accept(): self.view.removeEventCallbackPivy(coin.SoMouseButtonEvent.getClassTypeId(),self.callbackClick) self.view.removeEventCallbackPivy(coin.SoLocation2Event.getClassTypeId(),self.callbackMove) obj = FreeCADGui.Snapper.lastSnappedObject FreeCADGui.Snapper.off() self.ui.offUi() if callback: if len(inspect.getargspec(callback).args) > 2: callback(self.pt,obj) else: callback(self.pt) self.pt = None def cancel(): self.view.removeEventCallbackPivy(coin.SoMouseButtonEvent.getClassTypeId(),self.callbackClick) self.view.removeEventCallbackPivy(coin.SoLocation2Event.getClassTypeId(),self.callbackMove) FreeCADGui.Snapper.off() self.ui.offUi() if callback: callback(None) # adding callback functions self.ui.pointUi(cancel=cancel,getcoords=getcoords,extra=extradlg,rel=bool(last)) self.callbackClick = self.view.addEventCallbackPivy(coin.SoMouseButtonEvent.getClassTypeId(),click) self.callbackMove = self.view.addEventCallbackPivy(coin.SoLocation2Event.getClassTypeId(),move)
def execute(self, obj): if len(obj.InList) != 1: return if Draft.getType(obj.InList[0]) != "Structure": return if not obj.InList[0].Shape: return if not obj.Base: return if not obj.Base.Shape: return if not obj.Base.Shape.Wires: return if not obj.Diameter.Value: return if not obj.Amount: return father = obj.InList[0] 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) bpoint, bvec = self.getBaseAndAxis(obj) if not bpoint: return axis = obj.Base.Placement.Rotation.multVec(FreeCAD.Vector(0, 0, -1)) size = (ArchCommands.projectToVector(father.Shape.copy(), axis)).Length if hasattr(obj, "Direction"): if not DraftVecUtils.isNull(obj.Direction): axis = FreeCAD.Vector(obj.Direction) #.normalize() # don't normalize so the vector can also be used to determine the distance size = axis.Length #print axis #print size if (obj.OffsetStart.Value + obj.OffsetEnd.Value) > size: return # all tests ok! pl = obj.Placement import Part circle = Part.makeCircle(obj.Diameter.Value / 2, bpoint, bvec) circle = Part.Wire(circle) try: bar = wire.makePipeShell([circle], True, False, 2) except: print "Arch: error sweeping rebar profile along the base sketch" return # building final shape shapes = [] if obj.Amount == 1: offset = DraftVecUtils.scaleTo(axis, size / 2) bar.translate(offset) shapes.append(bar) if hasattr(obj, "Spacing"): obj.Spacing = 0 else: if obj.OffsetStart.Value: baseoffset = DraftVecUtils.scaleTo(axis, obj.OffsetStart.Value) else: baseoffset = None interval = size - (obj.OffsetStart.Value + obj.OffsetEnd.Value) interval = interval / (obj.Amount - 1) vinterval = DraftVecUtils.scaleTo(axis, interval) for i in range(obj.Amount): if i == 0: if baseoffset: bar.translate(baseoffset) shapes.append(bar) else: bar = bar.copy() bar.translate(vinterval) shapes.append(bar) if hasattr(obj, "Spacing"): obj.Spacing = interval if shapes: obj.Shape = Part.makeCompound(shapes) obj.Placement = pl
def snap(self,screenpos,lastpoint=None,active=True,constrain=False): """snap(screenpos,lastpoint=None,active=True,constrain=False): returns a snapped point from the given (x,y) screenpos (the position of the mouse cursor), active is to activate active point snapping or not (passive), lastpoint is an optional other point used to draw an imaginary segment and get additional snap locations. Constrain can be True to constrain the point against the closest working plane axis. Screenpos can be a list, a tuple or a coin.SbVec2s object.""" global Part, DraftGeomUtils import Part, DraftGeomUtils if not hasattr(self,"toolbar"): self.makeSnapToolBar() mw = getMainWindow() bt = mw.findChild(QtGui.QToolBar,"Draft Snap") if not bt: mw.addToolBar(self.toolbar) else: if Draft.getParam("showSnapBar"): bt.show() def cstr(point): "constrains if needed" if constrain or self.mask: fpt = self.constrain(point,lastpoint) else: self.unconstrain() fpt = point if self.radiusTracker: self.radiusTracker.update(fpt) return fpt snaps = [] self.snapInfo = None # type conversion if needed if isinstance(screenpos,list): screenpos = tuple(screenpos) elif isinstance(screenpos,coin.SbVec2s): screenpos = tuple(screenpos.getValue()) elif not isinstance(screenpos,tuple): print "snap needs valid screen position (list, tuple or sbvec2s)" return None # setup trackers if needed self.setTrackers() # getting current snap Radius self.radius = self.getScreenDist(Draft.getParam("snapRange"),screenpos) if self.radiusTracker: self.radiusTracker.update(self.radius) self.radiusTracker.off() # activate snap oldActive = False if Draft.getParam("alwaysSnap"): oldActive = active active = True if not self.active: active = False self.setCursor('passive') if self.tracker: self.tracker.off() if self.extLine: self.extLine.off() if self.trackLine: self.trackLine.off() point = self.getApparentPoint(screenpos[0],screenpos[1]) # setup a track line if we got a last point if lastpoint: if not self.trackLine: self.trackLine = DraftTrackers.lineTracker() self.trackLine.p1(lastpoint) # check if we snapped to something self.snapInfo = Draft.get3DView().getObjectInfo((screenpos[0],screenpos[1])) # checking if parallel to one of the edges of the last objects or to a polar direction if active: eline = None point,eline = self.snapToPolar(point,lastpoint) point,eline = self.snapToExtensions(point,lastpoint,constrain,eline) if not self.snapInfo: # nothing has been snapped, check fro grid snap if active: point = self.snapToGrid(point) fp = cstr(point) if self.trackLine and lastpoint: self.trackLine.p2(fp) self.trackLine.on() return fp else: # we have an object to snap to obj = FreeCAD.ActiveDocument.getObject(self.snapInfo['Object']) if not obj: return cstr(point) self.lastSnappedObject = obj if hasattr(obj.ViewObject,"Selectable"): if not obj.ViewObject.Selectable: return cstr(point) if not active: # passive snapping snaps = [self.snapToVertex(self.snapInfo)] else: # first stick to the snapped object s = self.snapToVertex(self.snapInfo) if s: point = s[0] # active snapping comp = self.snapInfo['Component'] if (Draft.getType(obj) == "Wall") and not oldActive: edges = [] for o in [obj]+obj.Additions: if Draft.getType(o) == "Wall": if o.Base: edges.extend(o.Base.Shape.Edges) for edge in edges: snaps.extend(self.snapToEndpoints(edge)) snaps.extend(self.snapToMidpoint(edge)) snaps.extend(self.snapToPerpendicular(edge,lastpoint)) snaps.extend(self.snapToIntersection(edge)) snaps.extend(self.snapToElines(edge,eline)) elif obj.isDerivedFrom("Part::Feature"): if (not self.maxEdges) or (len(obj.Edges) <= self.maxEdges): if "Edge" in comp: # we are snapping to an edge en = int(comp[4:])-1 if len(obj.Shape.Edges) > en: edge = obj.Shape.Edges[en] snaps.extend(self.snapToEndpoints(edge)) snaps.extend(self.snapToMidpoint(edge)) snaps.extend(self.snapToPerpendicular(edge,lastpoint)) #snaps.extend(self.snapToOrtho(edge,lastpoint,constrain)) # now part of snapToPolar snaps.extend(self.snapToIntersection(edge)) snaps.extend(self.snapToElines(edge,eline)) if DraftGeomUtils.geomType(edge) == "Circle": # the edge is an arc, we have extra options snaps.extend(self.snapToAngles(edge)) snaps.extend(self.snapToCenter(edge)) elif "Vertex" in comp: # directly snapped to a vertex snaps.append(self.snapToVertex(self.snapInfo,active=True)) elif comp == '': # workaround for the new view provider snaps.append(self.snapToVertex(self.snapInfo,active=True)) else: # all other cases (face, etc...) default to passive snap snapArray = [self.snapToVertex(self.snapInfo)] elif Draft.getType(obj) == "Dimension": # for dimensions we snap to their 3 points for pt in [obj.Start,obj.End,obj.Dimline]: snaps.append([pt,'endpoint',pt]) elif Draft.getType(obj) == "Mesh": # for meshes we only snap to vertices snaps.extend(self.snapToEndpoints(obj.Mesh)) elif Draft.getType(obj) == "Points": # for points we only snap to points snaps.extend(self.snapToEndpoints(obj.Points)) # updating last objects list if not self.lastObj[1]: self.lastObj[1] = obj.Name elif self.lastObj[1] != obj.Name: self.lastObj[0] = self.lastObj[1] self.lastObj[1] = obj.Name if not snaps: return cstr(point) # calculating the nearest snap point shortest = 1000000000000000000 origin = Vector(self.snapInfo['x'],self.snapInfo['y'],self.snapInfo['z']) winner = [Vector(0,0,0),None,Vector(0,0,0)] for snap in snaps: if (not snap) or (snap[0] == None): print "debug: Snapper: invalid snap point: ",snaps else: delta = snap[0].sub(origin) if delta.Length < shortest: shortest = delta.Length winner = snap # see if we are out of the max radius, if any if self.radius: dv = point.sub(winner[2]) if (dv.Length > self.radius): if (not oldActive) and self.isEnabled("passive"): winner = self.snapToVertex(self.snapInfo) # setting the cursors if self.tracker: self.tracker.setCoords(winner[2]) self.tracker.setMarker(self.mk[winner[1]]) self.tracker.on() # setting the trackline fp = cstr(winner[2]) if self.trackLine and lastpoint: self.trackLine.p2(fp) self.trackLine.on() # set the cursor self.setCursor(winner[1]) # return the final point return fp
def taskbox(self): "sets up a taskbox widget" w = QtGui.QWidget() ui = FreeCADGui.UiLoader() w.setWindowTitle(translate("Arch", "Wall options").decode("utf8")) grid = QtGui.QGridLayout(w) matCombo = QtGui.QComboBox() matCombo.addItem(translate("Arch", "Wall Presets...")) self.multimats = [] self.MultiMat = None for o in FreeCAD.ActiveDocument.Objects: if Draft.getType(o) == "MultiMaterial": self.multimats.append(o) matCombo.addItem(o.Label) if hasattr(FreeCAD, "LastArchMultiMaterial"): for i, o in enumerate(self.multimats): if o.Name == FreeCAD.LastArchMultiMaterial: matCombo.setCurrentIndex(i + 1) self.MultiMat = o grid.addWidget(matCombo, 0, 0, 1, 2) label5 = QtGui.QLabel(translate("Arch", "Length").decode("utf8")) self.Length = ui.createWidget("Gui::InputField") self.Length.setText("0.00 mm") grid.addWidget(label5, 1, 0, 1, 1) grid.addWidget(self.Length, 1, 1, 1, 1) label1 = QtGui.QLabel(translate("Arch", "Width").decode("utf8")) value1 = ui.createWidget("Gui::InputField") value1.setText( FreeCAD.Units.Quantity(self.Width, FreeCAD.Units.Length).UserString) grid.addWidget(label1, 2, 0, 1, 1) grid.addWidget(value1, 2, 1, 1, 1) label2 = QtGui.QLabel(translate("Arch", "Height").decode("utf8")) value2 = ui.createWidget("Gui::InputField") value2.setText( FreeCAD.Units.Quantity(self.Height, FreeCAD.Units.Length).UserString) grid.addWidget(label2, 3, 0, 1, 1) grid.addWidget(value2, 3, 1, 1, 1) label3 = QtGui.QLabel(translate("Arch", "Alignment").decode("utf8")) value3 = QtGui.QComboBox() items = ["Center", "Left", "Right"] value3.addItems(items) value3.setCurrentIndex(items.index(self.Align)) grid.addWidget(label3, 4, 0, 1, 1) grid.addWidget(value3, 4, 1, 1, 1) label4 = QtGui.QLabel(translate("Arch", "Con&tinue").decode("utf8")) value4 = QtGui.QCheckBox() value4.setObjectName("ContinueCmd") value4.setLayoutDirection(QtCore.Qt.RightToLeft) label4.setBuddy(value4) if hasattr(FreeCADGui, "draftToolBar"): value4.setChecked(FreeCADGui.draftToolBar.continueMode) self.continueCmd = FreeCADGui.draftToolBar.continueMode grid.addWidget(label4, 5, 0, 1, 1) grid.addWidget(value4, 5, 1, 1, 1) QtCore.QObject.connect(self.Length, QtCore.SIGNAL("valueChanged(double)"), self.setLength) QtCore.QObject.connect(value1, QtCore.SIGNAL("valueChanged(double)"), self.setWidth) QtCore.QObject.connect(value2, QtCore.SIGNAL("valueChanged(double)"), self.setHeight) QtCore.QObject.connect(value3, QtCore.SIGNAL("currentIndexChanged(int)"), self.setAlign) QtCore.QObject.connect(value4, QtCore.SIGNAL("stateChanged(int)"), self.setContinue) QtCore.QObject.connect(self.Length, QtCore.SIGNAL("returnPressed()"), value1.setFocus) QtCore.QObject.connect(self.Length, QtCore.SIGNAL("returnPressed()"), value1.selectAll) QtCore.QObject.connect(value1, QtCore.SIGNAL("returnPressed()"), value2.setFocus) QtCore.QObject.connect(value1, QtCore.SIGNAL("returnPressed()"), value2.selectAll) QtCore.QObject.connect(value2, QtCore.SIGNAL("returnPressed()"), self.createFromGUI) QtCore.QObject.connect(matCombo, QtCore.SIGNAL("currentIndexChanged(int)"), self.setMat) return w
def getExtrusionData(self, obj): """returns (shape,extrusion vector,placement) or None""" import Part, DraftGeomUtils data = ArchComponent.Component.getExtrusionData(self, obj) if data: if not isinstance(data[0], list): # multifuses not considered here return data length = obj.Length.Value width = obj.Width.Value height = obj.Height.Value if not height: for p in obj.InList: if Draft.getType(p) == "Floor": if p.Height.Value: height = p.Height.Value if obj.Normal == Vector(0, 0, 0): normal = Vector(0, 0, 1) else: normal = Vector(obj.Normal) base = None placement = None basewires = None # build wall layers layers = [] if hasattr(obj, "Material"): if obj.Material: if hasattr(obj.Material, "Materials"): varwidth = 0 restwidth = width - sum(obj.Material.Thicknesses) if restwidth > 0: varwidth = [ t for t in obj.Material.Thicknesses if t == 0 ] if varwidth: varwidth = restwidth / len(varwidth) for t in obj.Material.Thicknesses: if t: layers.append(t) elif varwidth: layers.append(varwidth) if obj.Base: if obj.Base.isDerivedFrom("Part::Feature"): if obj.Base.Shape: if obj.Base.Shape.Solids: return None elif obj.Face > 0: if len(obj.Base.Shape.Faces) >= obj.Face: face = obj.Base.Shape.Faces[obj.Face - 1] # this wall is based on a specific face of its base object normal = face.normalAt(0, 0) if normal.getAngle(Vector(0, 0, 1)) > math.pi / 4: normal.multiply(width) base = face.extrude(normal) if obj.Align == "Center": base.translate( normal.negative().multiply(0.5)) elif obj.Align == "Right": base.translate(normal.negative()) else: normal.multiply(height) base = face.extrude(normal) base, placement = self.rebase(base) return (base, normal, placement) elif obj.Base.Shape.Faces: if not DraftGeomUtils.isCoplanar(obj.Base.Shape.Faces): return None else: base, placement = self.rebase(obj.Base.Shape) elif obj.Base.Shape.Wires: basewires = obj.Base.Shape.Wires elif len(obj.Base.Shape.Edges) == 1: basewires = [Part.Wire(obj.Base.Shape.Edges)] if basewires and width: if (len(basewires) == 1) and layers: basewires = [basewires[0] for l in layers] layeroffset = 0 baseface = None for i, wire in enumerate(basewires): e = wire.Edges[0] if isinstance(e.Curve, Part.Circle): dvec = e.Vertexes[0].Point.sub(e.Curve.Center) else: dvec = DraftGeomUtils.vec( wire.Edges[0]).cross(normal) if not DraftVecUtils.isNull(dvec): dvec.normalize() sh = None if obj.Align == "Left": off = obj.Offset.Value if layers: off = off + layeroffset dvec.multiply(layers[i]) layeroffset += layers[i] else: dvec.multiply(width) if off: dvec2 = DraftVecUtils.scaleTo(dvec, off) wire = DraftGeomUtils.offsetWire( wire, dvec2) w2 = DraftGeomUtils.offsetWire(wire, dvec) w1 = Part.Wire(Part.__sortEdges__(wire.Edges)) sh = DraftGeomUtils.bind(w1, w2) elif obj.Align == "Right": dvec = dvec.negative() off = obj.Offset.Value if layers: off = off + layeroffset dvec.multiply(layers[i]) layeroffset += layers[i] else: dvec.multiply(width) if off: dvec2 = DraftVecUtils.scaleTo(dvec, off) wire = DraftGeomUtils.offsetWire( wire, dvec2) w2 = DraftGeomUtils.offsetWire(wire, dvec) w1 = Part.Wire(Part.__sortEdges__(wire.Edges)) sh = DraftGeomUtils.bind(w1, w2) elif obj.Align == "Center": if layers: off = width / 2 - layeroffset d1 = Vector(dvec).multiply(off) w1 = DraftGeomUtils.offsetWire(wire, d1) layeroffset += layers[i] off = width / 2 - layeroffset d1 = Vector(dvec).multiply(off) w2 = DraftGeomUtils.offsetWire(wire, d1) else: dvec.multiply(width / 2) w1 = DraftGeomUtils.offsetWire(wire, dvec) dvec = dvec.negative() w2 = DraftGeomUtils.offsetWire(wire, dvec) sh = DraftGeomUtils.bind(w1, w2) if sh: sh.fix(0.1, 0, 1) # fixes self-intersecting wires f = Part.Face(sh) if baseface: if layers: baseface.append(f) else: baseface = baseface.fuse(f) else: if layers: baseface = [f] else: baseface = f if baseface: base, placement = self.rebase(baseface) else: if layers: totalwidth = sum(layers) offset = 0 base = [] for l in layers: l2 = length / 2 or 0.5 w1 = -totalwidth / 2 + offset w2 = w1 + l v1 = Vector(-l2, w1, 0) v2 = Vector(l2, w1, 0) v3 = Vector(l2, w2, 0) v4 = Vector(-l2, w2, 0) base.append( Part.Face(Part.makePolygon([v1, v2, v3, v4, v1]))) offset += l else: l2 = length / 2 or 0.5 w2 = width / 2 or 0.5 v1 = Vector(-l2, -w2, 0) v2 = Vector(l2, -w2, 0) v3 = Vector(l2, w2, 0) v4 = Vector(-l2, w2, 0) base = Part.Face(Part.makePolygon([v1, v2, v3, v4, v1])) placement = FreeCAD.Placement() if base and placement: extrusion = normal.multiply(height) return (base, extrusion, placement) return None
def compute(): QtGui.qApp.setOverrideCursor(QtCore.Qt.WaitCursor) if FreeCAD.ActiveDocument == None: FreeCAD.newDocument("Gear") oldDocumentObjects = App.ActiveDocument.Objects try: N = int(l1.text()) p = float(l2.text()) alfa = int(l3.text()) y = float( l4.text()) #standard value y<1 for gear drives y>1 for Gear pumps m = p / math.pi #standard value 0.06, 0.12, 0.25, 0.5, 1, 2, 4, 8, 16, 32, 60 (polish norm) c = float(l5.text()) * m #standard value 0,1*m - 0,3*m j = float(l6.text()) * m #standard value 0,015 - 0,04*m width = float(l7.text()) #gear width except ValueError: FreeCAD.Console.PrintError("Wrong input! Only numbers allowed...\n") #tooth height h = 2 * y * m + c #pitch diameter d = N * m #root diameter df = d - 2 * y * m - 2 * c #df=d-2hf where and hf=y*m+c #addendum diameter da = d + 2 * y * m #da=d+2ha where ha=y*m #base diameter for involute db = d * math.cos(math.radians(alfa)) #Base circle baseCircle = FreeCAD.ActiveDocument.addObject("Part::FeaturePython", "BaseCircle") Draft._Circle(baseCircle) Draft._ViewProviderDraft(baseCircle.ViewObject) baseCircle.Radius = db / 2 baseCircle.FirstAngle = 0.0 baseCircle.LastAngle = 0.0 #Root circle rootCircle = FreeCAD.ActiveDocument.addObject("Part::FeaturePython", "RootCircle") Draft._Circle(rootCircle) Draft._ViewProviderDraft(rootCircle.ViewObject) rootCircle.Radius = df / 2 rootCircle.FirstAngle = 0.0 rootCircle.LastAngle = 0.0 #Addendum circle addendumCircle = FreeCAD.ActiveDocument.addObject("Part::FeaturePython", "AddendumCircle") Draft._Circle(addendumCircle) Draft._ViewProviderDraft(addendumCircle.ViewObject) addendumCircle.Radius = da / 2 addendumCircle.FirstAngle = 0.0 addendumCircle.LastAngle = 0.0 #Pitch circle pitchCircle = FreeCAD.ActiveDocument.addObject("Part::FeaturePython", "PitchCircle") Draft._Circle(pitchCircle) Draft._ViewProviderDraft(pitchCircle.ViewObject) pitchCircle.Radius = d / 2 pitchCircle.FirstAngle = 0.0 pitchCircle.LastAngle = 0.0 #************ Calculating right sides of teeth #Involute of base circle involute = [] involutee = [] involutesav = [] for t in range(0, 60, 1): x = db / 2 * (math.cos(math.radians(t)) + math.radians(t) * math.sin(math.radians(t))) y = db / 2 * (math.sin(math.radians(t)) - math.radians(t) * math.cos(math.radians(t))) involute.append(Part.Vertex(x, y, 0).Point) #************ Drawing rigth sides of teeth involutesav.extend(involute) involutee.extend(involute) for angle in range(1, N + 1, 1): involuteobj = FreeCAD.ActiveDocument.addObject( "Part::Feature", "InvoluteL" + str(angle)) involutee.insert(0, (0, 0, 0)) involuteshape = Part.makePolygon(involutee) involuteobj.Shape = involuteshape involutee = [] for num in range(0, 60, 1): point = involute.pop() pointt = Part.Vertex( point.x * math.cos(math.radians(angle * 360 / N)) - point.y * math.sin(math.radians(angle * 360 / N)), point.x * math.sin(math.radians(angle * 360 / N)) + point.y * math.cos(math.radians(angle * 360 / N)), 0).Point involutee.insert(0, pointt) involute.extend(involutesav) involutee = [] #************ Calculating difference between tooth spacing on BaseCircle and PitchCircle pc = App.ActiveDocument.getObject("PitchCircle") inv = App.ActiveDocument.getObject("InvoluteL1") cut = inv.Shape.cut(pc.Shape) # FreeCAD.ActiveDocument.addObject("Part::Feature","CutInv").Shape=cut invPoint = cut.Vertexes[0].Point diff = invPoint.y * 2 # instead of making axial symmetry and calculating point distance. anglediff = 2 * math.asin(diff / d) #************ Calculating left sides of teeth #************ Inversing Involute for num in range(0, 60, 1): point = involute.pop() pointt = Part.Vertex(point.x, point.y * -1, 0).Point involutee.insert(0, pointt) involute.extend(involutee) involutee = [] #Normal tooth size calculated as: 0,5* p - j j=m * 0,1 below are calculations # 0,5* p - m * 0,1 # 0,5* p - p /pi * 0,1 # 0,5*360/N - ((360/N)/pi)* 0,1 # 0,5*360/N - (360/N)*((1/pi)*0,1) j=(p/pi)*0,1 # 0,5*360/N - (360/N)*((p/pi)*0,1)/p # 0,5*360/N - (360/N)*( j )/p for num in range(0, 60, 1): point = involute.pop() pointt = Part.Vertex( point.x * math.cos(math.radians(180 / N - (360 / N) * (j / p)) + anglediff) - point.y * math.sin(math.radians(180 / N - (360 / N) * (j / p)) + anglediff), point.x * math.sin(math.radians(180 / N - (360 / N) * (j / p)) + anglediff) + point.y * math.cos(math.radians(180 / N - (360 / N) * (j / p)) + anglediff), 0).Point involutee.insert(0, pointt) involute.extend(involutee) involutesav = [] involutesav.extend(involute) #************ Drawing left sides of teeth for angle in range(1, N + 1, 1): involuteobj = FreeCAD.ActiveDocument.addObject( "Part::Feature", "InvoluteR" + str(angle)) involutee.insert(0, (0, 0, 0)) involuteshape = Part.makePolygon(involutee) involuteobj.Shape = involuteshape involutee = [] for num in range(0, 60, 1): point = involute.pop() pointt = Part.Vertex( point.x * math.cos(math.radians(angle * 360 / N)) - point.y * math.sin(math.radians(angle * 360 / N)), point.x * math.sin(math.radians(angle * 360 / N)) + point.y * math.cos(math.radians(angle * 360 / N)), 0).Point involutee.insert(0, pointt) involute.extend(involutesav) Gui.SendMsgToActiveView("ViewFit") #************ Forming teeth cutCircle = FreeCAD.ActiveDocument.addObject("Part::FeaturePython", "CutCircle") Draft._Circle(cutCircle) Draft._ViewProviderDraft(cutCircle.ViewObject) cutCircle.Radius = da # da because must be bigger than addendumCircle and bigger than whole construction da is right for this but it not has to be. cutCircle.FirstAngle = 0.0 cutCircle.LastAngle = 0.0 cutTool = cutCircle.Shape.cut(addendumCircle.Shape) #cutshape=Part.show(cutTool) gearShape = rootCircle.Shape for invNum in range(1, N + 1, 1): invL = App.ActiveDocument.getObject("InvoluteL" + str(invNum)) invR = App.ActiveDocument.getObject("InvoluteR" + str(invNum)) cutL = invL.Shape.cut(cutTool) cutR = invR.Shape.cut(cutTool) pointL = cutL.Vertexes.pop().Point pointR = cutR.Vertexes.pop().Point faceEdge = Part.makeLine(pointL, pointR) toothWhole = cutL.fuse(cutR) toothWhole = toothWhole.fuse(faceEdge) toothWire = Part.Wire(toothWhole.Edges) toothShape = Part.Face(toothWire) # tooth=App.ActiveDocument.addObject("Part::Feature","Tooth"+str(invNum)) # tooth.Shape=toothShape gearShape = gearShape.fuse(toothShape) for o in App.ActiveDocument.Objects: if oldDocumentObjects.count(o) == 0: App.ActiveDocument.removeObject(o.Name) gearFlat = App.ActiveDocument.addObject("Part::Feature", "GearFlat") gearFlat.Shape = gearShape Gui.ActiveDocument.getObject(gearFlat.Name).Visibility = False gear = App.ActiveDocument.addObject("Part::Extrusion", "Gear3D") gear.Base = gearFlat gear.Dir = (0, 0, width) App.ActiveDocument.recompute() if c1.isChecked() == True: gearMesh = App.ActiveDocument.addObject("Mesh::Feature", "Gear3D-mesh") faces = [] triangles = gear.Shape.tessellate( 1) # the number represents the precision of the tessellation) for tri in triangles[1]: face = [] for i in range(3): vindex = tri[i] face.append(triangles[0][vindex]) faces.append(face) mesh = Mesh.Mesh(faces) gearMesh.Mesh = mesh App.ActiveDocument.removeObject(gear.Name) App.ActiveDocument.removeObject(gearFlat.Name) App.ActiveDocument.recompute() Gui.SendMsgToActiveView("ViewFit") QtGui.qApp.restoreOverrideCursor() hide()
def getPoint(self, point=None, obj=None): "this function is called by the snapper when it has a 3D point" if obj: if Draft.getType(obj) == "Wall": if not obj in self.existing: self.existing.append(obj) if point == None: self.tracker.finalize() return self.points.append(point) if len(self.points) == 1: self.tracker.width(self.Width) self.tracker.height(self.Height) self.tracker.on() FreeCADGui.Snapper.getPoint(last=self.points[0], callback=self.getPoint, movecallback=self.update, extradlg=self.taskbox()) elif len(self.points) == 2: import Part l = Part.LineSegment( FreeCAD.DraftWorkingPlane.getLocalCoords(self.points[0]), FreeCAD.DraftWorkingPlane.getLocalCoords(self.points[1])) self.tracker.finalize() FreeCAD.ActiveDocument.openTransaction( translate("Arch", "Create Wall")) FreeCADGui.addModule("Arch") FreeCADGui.doCommand('import Part') FreeCADGui.doCommand('trace=Part.LineSegment(FreeCAD.' + str(l.StartPoint) + ',FreeCAD.' + str(l.EndPoint) + ')') if not self.existing: # no existing wall snapped, just add a default wall self.addDefault(l) else: if self.JOIN_WALLS_SKETCHES: # join existing subwalls first if possible, then add the new one w = joinWalls(self.existing) if w: if areSameWallTypes([w, self]): FreeCADGui.doCommand('FreeCAD.ActiveDocument.' + w.Name + '.Base.addGeometry(trace)') else: # if not possible, add new wall as addition to the existing one self.addDefault(l) if self.AUTOJOIN: FreeCADGui.doCommand( 'Arch.addComponents(FreeCAD.ActiveDocument.' + FreeCAD.ActiveDocument.Objects[-1].Name + ',FreeCAD.ActiveDocument.' + w.Name + ')') else: self.addDefault(l) else: # add new wall as addition to the first existing one self.addDefault(l) if self.AUTOJOIN: FreeCADGui.doCommand( 'Arch.addComponents(FreeCAD.ActiveDocument.' + FreeCAD.ActiveDocument.Objects[-1].Name + ',FreeCAD.ActiveDocument.' + self.existing[0].Name + ')') FreeCAD.ActiveDocument.commitTransaction() FreeCAD.ActiveDocument.recompute() if self.continueCmd: self.Activated()
def getSVG(section, renderMode="Wireframe", allOn=False, showHidden=False, scale=1, rotation=0, linewidth=1, lineColor=(0.0, 0.0, 0.0), fontsize=1, showFill=False, fillColor=(0.8, 0.8, 0.8), techdraw=False): """getSVG(section, [renderMode, allOn, showHidden, scale, rotation, linewidth, lineColor, fontsize, showFill, fillColor, techdraw]): returns an SVG fragment from an Arch section plane. If allOn is True, all cut objects are shown, regardless if they are visible or not. renderMode can be Wireframe (default) or Solid to use the Arch solid renderer. If showHidden is True, the hidden geometry above the section plane is shown in dashed line. If showFill is True, the cut areas get filled with a pattern. lineColor -- Color of lines for the renderMode "Wireframe". fillColor -- If showFill is True and renderMode is "Wireframe", the cut areas are filled with fillColor. """ if not section.Objects: return "" import Part, DraftGeomUtils p = FreeCAD.Placement(section.Placement) direction = p.Rotation.multVec(FreeCAD.Vector(0, 0, 1)) objs = Draft.getGroupContents(section.Objects, walls=True, addgroups=True) if not allOn: objs = Draft.removeHidden(objs) # separate spaces and Draft objects spaces = [] nonspaces = [] drafts = [] windows = [] cutface = None for o in objs: if Draft.getType(o) == "Space": spaces.append(o) elif Draft.getType(o) in ["Dimension", "Annotation", "Label"]: drafts.append(o) elif o.isDerivedFrom("Part::Part2DObject"): drafts.append(o) else: nonspaces.append(o) if Draft.getType(o) == "Window": windows.append(o) objs = nonspaces archUserParameters = FreeCAD.ParamGet( "User parameter:BaseApp/Preferences/Mod/Arch") scaledLineWidth = linewidth / scale svgLineWidth = str(scaledLineWidth) + 'px' st = archUserParameters.GetFloat("CutLineThickness", 2) svgCutLineWidth = str(scaledLineWidth * st) + 'px' yt = archUserParameters.GetFloat("SymbolLineThickness", 0.6) svgSymbolLineWidth = str(linewidth * yt) hiddenPattern = archUserParameters.GetString("archHiddenPattern", "30,10") svgHiddenPattern = hiddenPattern.replace(" ", "") fillpattern = '<pattern id="sectionfill" patternUnits="userSpaceOnUse" patternTransform="matrix(5,0,0,5,0,0)"' fillpattern += ' x="0" y="0" width="10" height="10">' fillpattern += '<g>' fillpattern += '<rect width="10" height="10" style="stroke:none; fill:#ffffff" /><path style="stroke:#000000; stroke-width:1" d="M0,0 l10,10" /></g></pattern>' svgLineColor = Draft.getrgb(lineColor) svg = '' # reading cached version svgcache = None if hasattr(section.Proxy, "svgcache") and section.Proxy.svgcache: svgcache = section.Proxy.svgcache[0] if section.Proxy.svgcache[1] != renderMode: svgcache = None if section.Proxy.svgcache[2] != showHidden: svgcache = None if section.Proxy.svgcache[3] != showFill: svgcache = None # generating SVG if renderMode in ["Solid", 1]: if not svgcache: svgcache = '' # render using the Arch Vector Renderer import ArchVRM, WorkingPlane wp = WorkingPlane.plane() wp.setFromPlacement(section.Placement) #wp.inverse() render = ArchVRM.Renderer() render.setWorkingPlane(wp) render.addObjects(objs) if showHidden: render.cut(section.Shape, showHidden) else: render.cut(section.Shape) svgcache += '<g transform="scale(1,-1)">\n' svgcache += render.getViewSVG(linewidth="SVGLINEWIDTH") svgcache += fillpattern svgcache += render.getSectionSVG(linewidth="SVGCUTLINEWIDTH", fillpattern="sectionfill") if showHidden: svgcache += render.getHiddenSVG(linewidth="SVGLINEWIDTH") svgcache += '</g>\n' # print(render.info()) section.Proxy.svgcache = [ svgcache, renderMode, showHidden, showFill ] else: if not svgcache: svgcache = "" # render using the Drawing module import Drawing, Part shapes, hshapes, sshapes, cutface, cutvolume, invcutvolume = getCutShapes( objs, section, showHidden) if shapes: baseshape = Part.makeCompound(shapes) style = { 'stroke': "SVGLINECOLOR", 'stroke-width': "SVGLINEWIDTH" } svgcache += Drawing.projectToSVG(baseshape, direction, hStyle=style, h0Style=style, h1Style=style, vStyle=style, v0Style=style, v1Style=style) if hshapes: hshapes = Part.makeCompound(hshapes) style = { 'stroke': "SVGLINECOLOR", 'stroke-width': "SVGLINEWIDTH", 'stroke-dasharray': "SVGHIDDENPATTERN" } svgcache += Drawing.projectToSVG(hshapes, direction, hStyle=style, h0Style=style, h1Style=style, vStyle=style, v0Style=style, v1Style=style) if sshapes: if showFill: #svgcache += fillpattern svgcache += '<g transform="rotate(180)">\n' for s in sshapes: if s.Edges: #svg += Draft.getSVG(s,direction=direction.negative(),linewidth=0,fillstyle="sectionfill",color=(0,0,0)) # temporarily disabling fill patterns svgcache += Draft.getSVG( s, direction=direction.negative(), linewidth=0, fillstyle=Draft.getrgb(fillColor), color=lineColor) svgcache += "</g>\n" sshapes = Part.makeCompound(sshapes) style = { 'stroke': "SVGLINECOLOR", 'stroke-width': "SVGCUTLINEWIDTH" } svgcache += Drawing.projectToSVG(sshapes, direction, hStyle=style, h0Style=style, h1Style=style, vStyle=style, v0Style=style, v1Style=style) section.Proxy.svgcache = [ svgcache, renderMode, showHidden, showFill ] svgcache = svgcache.replace("SVGLINECOLOR", svgLineColor) svgcache = svgcache.replace("SVGLINEWIDTH", svgLineWidth) svgcache = svgcache.replace("SVGHIDDENPATTERN", svgHiddenPattern) svgcache = svgcache.replace("SVGCUTLINEWIDTH", svgCutLineWidth) svg += svgcache if drafts: if not techdraw: svg += '<g transform="scale(1,-1)">' for d in drafts: svg += Draft.getSVG(d, scale=scale, linewidth=svgSymbolLineWidth, fontsize=fontsize, direction=direction, color=lineColor, techdraw=techdraw, rotation=rotation) if not techdraw: svg += '</g>' # filter out spaces not cut by the section plane if cutface and spaces: spaces = [ s for s in spaces if s.Shape.BoundBox.intersect(cutface.BoundBox) ] if spaces: if not techdraw: svg += '<g transform="scale(1,-1)">' for s in spaces: svg += Draft.getSVG(s, scale=scale, linewidth=svgSymbolLineWidth, fontsize=fontsize, direction=direction, color=lineColor, techdraw=techdraw, rotation=rotation) if not techdraw: svg += '</g>' # add additional edge symbols from windows cutwindows = [] if cutface and windows: cutwindows = [ w.Name for w in windows if w.Shape.BoundBox.intersect(cutface.BoundBox) ] if windows: sh = [] for w in windows: if not hasattr(w.Proxy, "sshapes"): w.Proxy.execute(w) if hasattr(w.Proxy, "sshapes"): if w.Proxy.sshapes and (w.Name in cutwindows): c = Part.makeCompound(w.Proxy.sshapes) c.Placement = w.Placement sh.append(c) # buggy for now... #if hasattr(w.Proxy,"vshapes"): # if w.Proxy.vshapes: # c = Part.makeCompound(w.Proxy.vshapes) # c.Placement = w.Placement # sh.append(c) if sh: if not techdraw: svg += '<g transform="scale(1,-1)">' for s in sh: svg += Draft.getSVG(s, scale=scale, linewidth=svgSymbolLineWidth, fontsize=fontsize, fillstyle="none", direction=direction, color=lineColor, techdraw=techdraw, rotation=rotation) if not techdraw: svg += '</g>' return svg
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s') doc = FreeCAD.newDocument() """ # Aluminum profiles for the citometer base # ------------- X alum profiles # fb: front (y=0) bottom (z=0) """ h_alu_x_fb = comps.MisumiAlu30s6w8(40, "alu_x_fb", axis='x', cx=1, cy=1, cz=0) alu_x_fb = h_alu_x_fb.fco # the FreeCad Object # bb: back (y=0) bottom (z=0) alu_x_bb = Draft.clone(alu_x_fb) alu_x_bb.Label = "alu_x_bb" alu_x_bb.Placement.Base = (FreeCAD.Vector(0, 50, 0)) # ------------------ Shaft holders SK12 ------------------------------ # f= f; r: right. hole_x = 0 -> hole facing Y axis h_sk12_fr = comps.Sk(size=12, name="sk12_fr", hole_x=0, cx=1, cy=1) sk12_fr = h_sk12_fr.fco # the FreeCad Object # ROD_Y_SEP is the separation of the Y RODs sk12_fr.Placement.Base = FreeCAD.Vector(20, 15, 30) # f= front; l: left sk12_fl = Draft.clone(sk12_fr) sk12_fl.Label = "sk12_fl" sk12_fl.Placement.Base = FreeCAD.Vector(-20, 15, 30) #alu_y_lb.Placement.Base = alu_y_basepos + alu_y_xendpos
def getExtrusionData(self,obj): """returns (shape,extrusion vector,placement) or None""" import Part,DraftGeomUtils data = ArchComponent.Component.getExtrusionData(self,obj) if data: if not isinstance(data[0],list): # multifuses not considered here return data length = obj.Length.Value width = obj.Width.Value height = obj.Height.Value normal = None if not height: for p in obj.InList: if Draft.getType(p) == "Floor": if p.Height.Value: height = p.Height.Value base = None placement = None if obj.Base: if obj.Base.isDerivedFrom("Part::Feature"): if obj.Base.Shape: if obj.Base.Shape.Solids: return None elif obj.Base.Shape.Faces: if not DraftGeomUtils.isCoplanar(obj.Base.Shape.Faces): return None else: base,placement = self.rebase(obj.Base.Shape) normal = obj.Base.Shape.Faces[0].normalAt(0,0) normal = placement.inverse().Rotation.multVec(normal) elif obj.Base.Shape.Wires: baseface = None if hasattr(obj,"FaceMaker"): if obj.FaceMaker != "None": try: baseface = Part.makeFace(obj.Base.Shape.Wires,"Part::FaceMaker"+str(obj.FaceMaker)) except: FreeCAD.Console.PrintError(translate("Arch","Facemaker returned an error")+"\n") return None if len(baseface.Faces) > 1: baseface = baseface.Faces[0] normal = baseface.normalAt(0,0) normal = placement.inverse().Rotation.multVec(normal) if not baseface: for w in obj.Base.Shape.Wires: w.fix(0.1,0,1) # fixes self-intersecting wires f = Part.Face(w) if baseface: baseface = baseface.fuse(f) else: baseface = f normal = f.normalAt(0,0) base,placement = self.rebase(baseface) elif (len(obj.Base.Shape.Edges) == 1) and (len(obj.Base.Shape.Vertexes) == 1): # closed edge w = Part.Wire(obj.Base.Shape.Edges[0]) baseface = Part.Face(w) base,placement = self.rebase(baseface) elif length and width and height: if (length > height) and (obj.Role != "Slab"): h2 = height/2 or 0.5 w2 = width/2 or 0.5 v1 = Vector(0,-w2,-h2) v2 = Vector(0,-w2,h2) v3 = Vector(0,w2,h2) v4 = Vector(0,w2,-h2) else: l2 = length/2 or 0.5 w2 = width/2 or 0.5 v1 = Vector(-l2,-w2,0) v2 = Vector(l2,-w2,0) v3 = Vector(l2,w2,0) v4 = Vector(-l2,w2,0) import Part baseface = Part.Face(Part.makePolygon([v1,v2,v3,v4,v1])) base,placement = self.rebase(baseface) if base and placement: if obj.Normal == Vector(0,0,0): if not normal: normal = Vector(0,0,1) else: normal = Vector(obj.Normal) if (length > height) and (obj.Role != "Slab"): extrusion = normal.multiply(length) else: extrusion = normal.multiply(height) return (base,extrusion,placement) return None
def removeComponents(objectsList, host=None): '''removeComponents(objectsList,[hostObject]): removes the given component or the components from the given list from their parents. If a host object is specified, this function will try adding the components as holes to the host object instead.''' if not isinstance(objectsList, list): objectsList = [objectsList] if host: if Draft.getType(host) in [ "Wall", "Structure", "Window", "Roof", "Stairs" ]: if hasattr(host, "Tool"): if objectsList[0] == host.Tool: host.Tool = None if hasattr(host, "Axes"): a = host.Axes for o in objectsList[:]: if o in a: a.remove(o) objectsList.remove(o) s = host.Subtractions for o in objectsList: if not o in s: s.append(o) if Draft.getType(o) == "Window": # fix for sketch-based windows if o.Base: if o.Base.Support: if isinstance(o.Base.Support, tuple): if o.Base.Support[0].Name == host.Name: FreeCAD.Console.PrintMessage( translate( "Arch", "removing sketch support to avoid cross-referencing" )) o.Base.Support = None elif o.Base.Support.Name == host.Name: FreeCAD.Console.PrintMessage( translate( "Arch", "removing sketch support to avoid cross-referencing" )) o.Base.Support = None elif o.Base.ExternalGeometry: for i in range(len(o.Base.ExternalGeometry)): if o.Base.ExternalGeometry[i][ 0].Name == host.Name: o.Base.delExternal(i) FreeCAD.Console.PrintMessage( translate( "Arch", "removing sketch support to avoid cross-referencing" )) break host.Subtractions = s else: for o in objectsList: if o.InList: h = o.InList[0] tp = Draft.getType(h) if tp in ["Floor", "Building", "Site"]: c = h.Components if o in c: c.remove(o) h.Components = c o.ViewObject.show() elif tp in ["Wall", "Structure"]: a = h.Additions s = h.Subtractions if o in a: a.remove(o) h.Additions = a o.ViewObject.show() elif o in s: s.remove(o) h.Subtractions = s o.ViewObject.show() elif o == s.Base: s.Base = None o.ViewObject.show() elif tp in ["SectionPlane"]: a = h.Objects if o in a: a.remove(o) h.Objects = a
def survey(callback=False): """survey(): starts survey mode, where you can click edges and faces to get their lengths or area. Clicking on no object (on an empty area) stops survey mode.""" if not callback: if hasattr(FreeCAD, "SurveyObserver"): for label in FreeCAD.SurveyObserver.labels: FreeCAD.ActiveDocument.removeObject(label) FreeCADGui.Selection.removeObserver(FreeCAD.SurveyObserver) del FreeCAD.SurveyObserver if FreeCAD.GuiUp: if hasattr(FreeCADGui, "draftToolBar"): FreeCADGui.draftToolBar.offUi() else: FreeCAD.SurveyObserver = _SurveyObserver(callback=survey) FreeCADGui.Selection.addObserver(FreeCAD.SurveyObserver) if FreeCAD.GuiUp: if hasattr(FreeCADGui, "draftToolBar"): FreeCADGui.draftToolBar.selectUi(callback=survey) else: sel = FreeCADGui.Selection.getSelectionEx() if not sel: if hasattr(FreeCAD, "SurveyObserver"): for label in FreeCAD.SurveyObserver.labels: FreeCAD.ActiveDocument.removeObject(label) FreeCADGui.Selection.removeObserver(FreeCAD.SurveyObserver) del FreeCAD.SurveyObserver if FreeCAD.GuiUp: if hasattr(FreeCADGui, "draftToolBar"): FreeCADGui.draftToolBar.offUi() else: if hasattr(FreeCAD, "SurveyObserver"): basesel = FreeCAD.SurveyObserver.selection newsels = [] for o in sel: found = False for eo in basesel: if o.ObjectName == eo.ObjectName: if o.SubElementNames == eo.SubElementNames: found = True if not found: newsels.append(o) if newsels: from pivy import coin pr = Draft.getParam("dimPrecision", 2) for o in newsels: if o.Object.isDerivedFrom("Part::Feature"): n = o.Object.Label if not o.HasSubObjects: # entire object anno = FreeCAD.ActiveDocument.addObject( "App::AnnotationLabel", "surveyLabel") anno.BasePosition = o.Object.Shape.CenterOfMass FreeCAD.SurveyObserver.labels.append(anno.Name) t = "" if o.Object.Shape.Solids: t = str(round(o.Object.Shape.Volume, pr)) anno.LabelText = "v " + t FreeCAD.Console.PrintMessage( "Object: " + n + ", Element: Whole, Volume: " + t + "\n") elif o.Object.Shape.Faces: t = str(round(o.Object.Shape.Area, pr)) anno.LabelText = "a " + t FreeCAD.Console.PrintMessage( "Object: " + n + ", Element: Whole, Area: " + t + "\n") else: t = str(round(o.Object.Shape.Length, pr)) anno.LabelText = "l " + t FreeCAD.Console.PrintMessage( "Object: " + n + ", Element: Whole, Length: " + t + "\n") if FreeCAD.GuiUp and t: QtGui.qApp.clipboard().setText(t) else: # single element(s) for el in o.SubElementNames: e = getattr(o.Object.Shape, el) anno = FreeCAD.ActiveDocument.addObject( "App::AnnotationLabel", "surveyLabel") if "Vertex" in el: anno.BasePosition = e.Point else: anno.BasePosition = e.CenterOfMass FreeCAD.SurveyObserver.labels.append( anno.Name) t = "" if "Face" in el: t = str(round(e.Area, pr)) anno.LabelText = "a " + t FreeCAD.Console.PrintMessage( "Object: " + n + ", Element: " + el + ", Area: " + t + "\n") elif "Edge" in el: t = str(round(e.Length, pr)) anno.LabelText = "l " + t FreeCAD.Console.PrintMessage( "Object: " + n + ", Element: " + el + ", Length: " + t + "\n") elif "Vertex" in el: t = str(round(e.Z, pr)) anno.LabelText = "z " + t FreeCAD.Console.PrintMessage( "Object: " + n + ", Element: " + el + ", Zcoord: " + t + "\n") if FreeCAD.GuiUp and t: QtGui.qApp.clipboard().setText(t) FreeCAD.SurveyObserver.selection.extend(newsels)
def draw_S800(): sweep_offset = 210 wing_span = 820 midWidth = 150 midLength = 200 WingInside_height_top = 25 WingInside_height_bot = 5 WingInside_length = 260 WingOutside_height_top = 20 WingOutside_height_bot = 3 WingOutside_length = 165 Middle_height_top = 40 Middle_height_bot = 20 Middle_length = WingInside_length WingletTop_height_top = 3 WingletTop_height_bot = 3 Winglet_angle_y = 10 Winglet_angle_z = 10 WingletBottom_height_top = WingletTop_height_top WingletBottom_height_bot = WingletTop_height_bot WingletBottom_length = WingOutside_length ElevonThickness = 1 ElevonLeftAngle = 20 ElevonRightAngle = -20 if FreeCAD.ActiveDocument is not None and FreeCAD.ActiveDocument.Name == "S800": FreeCAD.closeDocument(FreeCAD.ActiveDocument.Name) FreeCAD.setActiveDocument("") ActiveDocument = None FreeCAD.ActiveDocument = None doc = FreeCAD.newDocument('S800') SplineFoilWingInside = doc.addObject('Sketcher::SketchObject', 'SplineFoilWingInside') makeSplineFoilSketch(SplineFoilWingInside, WingInside_length, WingInside_height_top, WingInside_height_bot, ElevonThickness) SplineFoilWingInside.ViewObject.Visibility = False SplineFoilWingInside.Placement = Placement(Vector(midWidth / 2, 0.0, 1.0), Rotation(0.5, 0.5, 0.5, 0.5)) SplineFoilWingInside.ViewObject.Visibility = False SplineFoilWingOutside = doc.addObject('Sketcher::SketchObject', 'SplineFoilWingOutside') makeSplineFoilSketch(SplineFoilWingOutside, WingOutside_length, WingOutside_height_top, WingOutside_height_bot, ElevonThickness) SplineFoilWingOutside.ViewObject.Visibility = False SplineFoilWingOutside.Placement = Placement( Vector(wing_span / 2, sweep_offset, 1.0), Rotation(0.5, 0.5, 0.5, 0.5)) SplineFoilWingOutside.ViewObject.Visibility = False SplineFoilWingletBottom = doc.addObject('Sketcher::SketchObject', 'SplineFoilWingletBottom') makeSplineFoilSketch(SplineFoilWingletBottom, WingletBottom_length, WingletBottom_height_top, WingletBottom_height_bot, 0.5) SplineFoilWingletBottom.ViewObject.Visibility = False SplineFoilWingletBottom.Placement.Rotation.Axis = Vector(0.0, 0.0, 0.1) SplineFoilWingletBottom.Placement.Rotation.Angle = math.radians(90) SplineFoilWingletBottom.Placement.Base.y = sweep_offset SplineFoilWingletBottom.Placement.Base.x = wing_span / 2 + WingletTop_height_bot * 1.5 SplineFoilWingletBottom.Placement.Base.z = WingOutside_height_top SplineFoilWingletBottom.ViewObject.Visibility = False doc.recompute() Draft.rotate([SplineFoilWingletBottom], Winglet_angle_y, SplineFoilWingletBottom.Placement.Base, Vector(0, 1, 0), copy=False) doc.recompute() SplineFoilMiddle = doc.addObject('Sketcher::SketchObject', 'SplineFoilMiddle') makeSplineFoilSketch(SplineFoilMiddle, Middle_length, Middle_height_top, Middle_height_bot, ElevonThickness) SplineFoilMiddle.Placement = Placement(Vector(0.0, 0.0, 0.0), Rotation(0.5, 0.5, 0.5, 0.5)) SplineFoilMiddle.ViewObject.Visibility = False MiddleProfile = createSketch_MiddleProfile(doc) MiddleProfile.ViewObject.Visibility = False MiddlePart1 = CurvedShapes.makeCurvedSegment(SplineFoilMiddle, SplineFoilWingInside, [MiddleProfile], Items=4, Surface=True, Solid=True, Distribution='elliptic', DistributionReverse=True) MiddlePart1.Label = "MiddlePart1" MiddlePart1.ViewObject.Visibility = False MainWing = doc.addObject('Part::Loft', 'MainWing') MainWing.Sections = [SplineFoilWingInside, SplineFoilWingOutside] MainWing.Solid = True WingToWinglet = CurvedShapes.makeInterpolatedMiddle( SplineFoilWingOutside, SplineFoilWingletBottom, Surface=True, Solid=True) WingToWinglet.Label = "WingToWinglet" WingletProfile = makeWingletProfile(doc) WingletProfile.ViewObject.Visibility = False doc.recompute() Winglet = CurvedShapes.makeCurvedArray(SplineFoilWingletBottom, [WingletProfile], Items=8, OffsetStart=0.01, OffsetEnd=0.01, Surface=True, Solid=True) Winglet.Label = "Winget" doc.recompute() Draft.rotate([Winglet], Winglet_angle_y, SplineFoilWingletBottom.Placement.Base, Vector(0, 1, 0), copy=False) doc.recompute() sketchCutout = doc.addObject('Sketcher::SketchObject', 'sketchCutout') sketchCutout.addGeometry( Part.LineSegment(Vector(0.0, 400.0, 0.0), Vector(274.99999999950205, 400.0, 0.0)), False) sketchCutout.addGeometry( Part.LineSegment(Vector(274.99999999950205, 400.0, 0.0), Vector(75.0, 200.0, 0.0)), False) sketchCutout.addGeometry( Part.LineSegment(Vector(75.0, 200.0, 0.0), Vector(0.0, 200.0, 0.0)), False) sketchCutout.addGeometry( Part.LineSegment(Vector(0.0, 200.0, 0.0), Vector(0.0, 400.0, 0.0)), False) sketchCutout.addConstraint(Sketcher.Constraint('PointOnObject', 0, 1, -2)) sketchCutout.addConstraint(Sketcher.Constraint('Horizontal', 0)) sketchCutout.addConstraint(Sketcher.Constraint('Coincident', 0, 2, 1, 1)) sketchCutout.addConstraint(Sketcher.Constraint('Coincident', 1, 2, 2, 1)) sketchCutout.addConstraint(Sketcher.Constraint('PointOnObject', 2, 2, -2)) sketchCutout.addConstraint(Sketcher.Constraint('Horizontal', 2)) sketchCutout.addConstraint(Sketcher.Constraint('Coincident', 2, 2, 3, 1)) sketchCutout.addConstraint(Sketcher.Constraint('Coincident', 3, 2, 0, 1)) sketchCutout.addConstraint( Sketcher.Constraint('Angle', 1, 2, 2, 1, 2.356194)) sketchCutout.addConstraint( Sketcher.Constraint('DistanceX', 2, 2, 2, 1, midWidth / 2)) sketchCutout.addConstraint( Sketcher.Constraint('DistanceY', 2, 2, midLength)) sketchCutout.addConstraint( Sketcher.Constraint('DistanceY', 3, 1, 3, 2, midLength)) sketchCutout.ViewObject.Visibility = False cutout = doc.addObject('Part::Extrusion', 'cutout') cutout.Base = sketchCutout cutout.DirMode = "Normal" cutout.LengthFwd = 100.0 cutout.LengthRev = 100.0 cutout.Solid = True cutout.Symmetric = True cutout.ViewObject.Visibility = False MiddlePart = doc.addObject('Part::Cut', 'MiddlePart') MiddlePart.Base = MiddlePart1 MiddlePart.Tool = cutout cutpathPoints = [Vector(midWidth / 2, midLength, -WingInside_height_bot)] cutpathPoints.append( Vector( wing_span / 2, midLength + sweep_offset - WingInside_length + WingOutside_length, -WingOutside_height_bot)) cutpath = Draft.makeWire(cutpathPoints) cutpath.ViewObject.Visibility = False cutExtrude = doc.addObject('Part::Extrusion', 'cutExtrude') cutExtrude.Base = cutpath cutExtrude.DirMode = "Normal" cutExtrude.LengthFwd = WingInside_height_bot + WingInside_height_top doc.recompute() Wing = doc.addObject('Part::Cut', 'Wing') Wing.Base = MainWing Wing.Tool = cutout doc.recompute() WingSlice = BOPTools.SplitFeatures.makeSlice(name='WingSlice') WingSlice.Base = [Wing, cutExtrude][0] WingSlice.Tools = [Wing, cutExtrude][1:] WingSlice.Mode = 'Split' WingSlice.Proxy.execute(WingSlice) WingSlice.purgeTouched() WingSlice.ViewObject.Visibility = False for obj in WingSlice.ViewObject.Proxy.claimChildren(): obj.ViewObject.hide() WingAndElevon = CompoundTools.Explode.explodeCompound(WingSlice) Wing1 = WingAndElevon[0].Group[0] Wing1.Label = "Wing1" ElevonLeft = WingAndElevon[0].Group[1] ElevonLeft.Label = "ElevonLeft" HalfWing = doc.addObject('Part::Compound', 'HalfWing') HalfWing.Links = [MiddlePart, Wing1, WingToWinglet, Winglet] FullWing = doc.addObject('Part::Mirroring', 'FullWing') FullWing.Normal = Vector(1.0, 0.0, 0.0) FullWing.Source = HalfWing ElevonRight1 = Draft.clone(ElevonLeft) ElevonRight1.ViewObject.Visibility = False ElevonRight = doc.addObject('Part::Mirroring', 'ElevonRight') ElevonRight.Normal = Vector(1.0, 0.0, 0.0) ElevonRight.Source = ElevonRight1 doc.recompute() axis = cutpathPoints[1].sub(cutpathPoints[0]) center = ElevonLeft.Placement.Base.add( Vector(midWidth / 2, midLength, ElevonLeft.Shape.BoundBox.ZMax)) Draft.rotate([ElevonLeft], ElevonLeftAngle, center, axis=axis, copy=False) Draft.rotate([ElevonRight1], ElevonRightAngle, center, axis=axis, copy=False) FreeCADGui.activeDocument().activeView().viewIsometric() FreeCADGui.SendMsgToActiveView("ViewFit") return
def buildObject(el, queue, refList, app): #expand and extract elements needed for object construction name, pos, b, objtype, tr = el queue.remove(el) #build the placement from the vector and quaternion stored in the xml file base = FreeCAD.Vector(float(pos['x']), float(pos['y']), float(pos['z'])) quat = [ float(pos['q0']), float(pos['q1']), float(pos['q2']), float(pos['q3']) ] q0, q1, q2, q3 = quat angle = 2 * math.acos(q3) axis = FreeCAD.Vector(q0, q1, q2) place = FreeCAD.Placement(base, axis, angle) isCreated = False defpnt = FreeCAD.Vector() defdir = FreeCAD.Vector(0, 0, 1) defplace = FreeCAD.Placement() #handler to determine which object constructor to call if objtype == 'box': isCreated = True part = Part.makeBox(float(b['length']), float(b['width']), float(b['height'])) obj = app.ActiveDocument.addObject('Part::Box', name) obj.Shape = part elif objtype == 'cylinder': isCreated = True part = Part.makeCylinder(float(b['radius']), float(b['height'])) obj = app.ActiveDocument.addObject('Part::Cylinder', name) obj.Shape = part elif objtype == 'cone': isCreated = True part = Part.makeCone(float(b['radius1']), float(b['radius2']), float(b['height'])) obj = app.ActiveDocument.addObject('Part::Cone', name) obj.Shape = part elif objtype == 'sphere': isCreated = True part = Part.makeSphere(float(b['radius']), defpnt, defdir, float(b['angle1']), float(b['angle2']), float(b['angle3'])) obj = app.ActiveDocument.addObject('Part::Sphere', name) obj.Shape = part elif objtype == 'torus': isCreated = True print el part = Part.makeTorus(float(b['radius1']), float(b['radius2']), defpnt, defdir, float(b['angle1']), float(b['angle2']), float(b['angle3'])) obj = app.ActiveDocument.addObject('Part::Torus', name) obj.Shape = part elif objtype == 'line': isCreated = False obj = app.ActiveDocument.addObject('Part::Part2DObjectPython', name) secpnt = FreeCAD.Vector(float(b['length']), 0, 0) Draft.Wire(obj) obj.Points = [defpnt, secpnt] obj.Closed = False obj.Support = None elif objtype == 'circle': isCreated = True obj = app.ActiveDocument.addObject('Part::Part2DObjectPython', name) Circle(obj) obj.Radius = float(b['radius']) startangle = float(b['angle1']) endangle = float(b['angle2']) if (startangle != None) and (endangle != None): obj.FirstAngle = startangle obj.LastAngle = endangle elif objtype == 'cut': isCreated = True obj = addObject('Part::MultiCut', name) obj.Shapes = [refList[b['base']], refList[b['tool']]] elif objtype == 'fusion': isCreated = True obj = addObject('Part::MultiFuse', name) obj.Shapes = [refList[b['base']], refList[b['tool']]] #refList[att['base']].Visibility = False #refList[att['tool']].Visibility = False elif objtype == 'common': isCreated = True obj = addObject('Part::MultiCommon', name) obj.Shapes = [refList[b['base']], refList[b['tool']]] elif objtype == 'extrude': isCreated = True obj = app.ActiveDocument.addObject('Part::Extrusion', name) obj.Base = refList[b['base']] obj.Dir = float( FreeCAD.Vector(float(b['valueX']), float(b['valueY']), float(b['valueZ']))) elif objtype == 'rectangle': isCreated = True obj = app.ActiveDocument.addObject("Part::Part2DObjectPython", name) Draft.Rectangle(obj) Draft.ViewProviderRectangle(obj.ViewObject) obj.Length = float(b['length']) obj.Height = float(b['height']) obj.Support = None obj.ViewObject.DisplayMode = "Wireframe" #Draft.formatObject(obj) app.ActiveDocument.recompute() #all objects are created with the default placement #now the actual placement is added to the FreeCAD object if isCreated: obj.Placement = place #add the mapping from the reference string(name of object) to the actual object. #this is needed in order to build 'extended objects' refList[name] = obj
def addSpaceBoundaries(space, subobjects): """addSpaceBoundaries(space,subobjects): adds the given subobjects to the given space""" import Draft if Draft.getType(space) == "Space": space.Proxy.addSubobjects(space, subobjects)
def reset(self): "resets the grid according to preferences settings" self.space = Draft.getParam("gridSpacing", 1) self.mainlines = Draft.getParam("gridEvery", 10) self.numlines = Draft.getParam("gridSize", 100) self.update()
pointlist.append( FreeCAD.Vector(curve[0], curve[1], float(j) * 1000)) a = Draft.makeWire(pointlist, closed=True) face = Part.Face(a) solid = face.extrude(Base.Vector(0, 0, float(k) * 1000)) return solid #test = GIS2BIM_FreeCAD_3DBuildings(curves3DBAG,heightData3DBAG) for i in curvesCadastralParcels: pointlist = [] for j in i: pointlist.append(FreeCAD.Vector(j[0], j[1], 0)) a = Draft.makeWire(pointlist, closed=False) for i, j, k in zip(textDataCadastralParcels[0], textDataCadastralParcels[1], textDataCadastralParcels[2]): ZAxis = FreeCAD.Vector(0, 0, 1) p1 = FreeCAD.Vector(i[0][0], i[0][1], 0) Place1 = FreeCAD.Placement(p1, FreeCAD.Rotation(ZAxis, -float(j))) Text1 = Draft.make_text(k, point=p1) Text1.ViewObject.FontSize = 150 Text1.Placement = Place1 for i, j, k in zip(textDataOpenbareRuimtenaam[0], textDataOpenbareRuimtenaam[1], textDataOpenbareRuimtenaam[2]): ZAxis = FreeCAD.Vector(0, 0, 1) p1 = FreeCAD.Vector(i[0][0], i[0][1], 0)