diff --git a/src/App/DocumentObjectGroup.cpp b/src/App/DocumentObjectGroup.cpp index ceb0fca72..1c16e0e51 100644 --- a/src/App/DocumentObjectGroup.cpp +++ b/src/App/DocumentObjectGroup.cpp @@ -37,7 +37,7 @@ PROPERTY_SOURCE(App::DocumentObjectGroup, App::DocumentObject) DocumentObjectGroup::DocumentObjectGroup() { - ADD_PROPERTY_TYPE(Group,(0),"Base",(App::PropertyType)(Prop_ReadOnly|Prop_Output),"List of referenced objects"); + ADD_PROPERTY_TYPE(Group,(0),"Base",(App::PropertyType)(Prop_Output),"List of referenced objects"); } DocumentObjectGroup::~DocumentObjectGroup() @@ -179,13 +179,13 @@ PyObject *DocumentObjectGroup::getPyObject() return Py::new_reference_to(PythonObject); } -// Python Sketcher feature --------------------------------------------------------- +// Python feature --------------------------------------------------------- namespace App { /// @cond DOXERR PROPERTY_SOURCE_TEMPLATE(App::DocumentObjectGroupPython, App::DocumentObjectGroup) template<> const char* App::DocumentObjectGroupPython::getViewProviderName(void) const { - return "Gui::ViewProviderDocumentObjectGroup"; + return "Gui::ViewProviderDocumentObjectGroupPython"; } /// @endcond diff --git a/src/Gui/Application.cpp b/src/Gui/Application.cpp index 2ce260bc3..d62c36b4e 100644 --- a/src/Gui/Application.cpp +++ b/src/Gui/Application.cpp @@ -1420,6 +1420,7 @@ void Application::initTypes(void) Gui::ViewProviderDocumentObject ::init(); Gui::ViewProviderFeature ::init(); Gui::ViewProviderDocumentObjectGroup ::init(); + Gui::ViewProviderDocumentObjectGroupPython ::init(); Gui::ViewProviderGeometryObject ::init(); Gui::ViewProviderInventorObject ::init(); Gui::ViewProviderVRMLObject ::init(); diff --git a/src/Gui/ViewProviderDocumentObjectGroup.cpp b/src/Gui/ViewProviderDocumentObjectGroup.cpp index 14927fbc2..13b2be0f0 100644 --- a/src/Gui/ViewProviderDocumentObjectGroup.cpp +++ b/src/Gui/ViewProviderDocumentObjectGroup.cpp @@ -221,3 +221,15 @@ QIcon ViewProviderDocumentObjectGroup::getIcon() const QIcon::Normal, QIcon::On); return groupIcon; } + + +// Python feature ----------------------------------------------------------------------- + +namespace Gui { +/// @cond DOXERR +PROPERTY_SOURCE_TEMPLATE(Gui::ViewProviderDocumentObjectGroupPython, Gui::ViewProviderDocumentObjectGroup) +/// @endcond + +// explicit template instantiation +template class GuiExport ViewProviderPythonFeatureT; +} diff --git a/src/Gui/ViewProviderDocumentObjectGroup.h b/src/Gui/ViewProviderDocumentObjectGroup.h index 7157898e7..aab975750 100644 --- a/src/Gui/ViewProviderDocumentObjectGroup.h +++ b/src/Gui/ViewProviderDocumentObjectGroup.h @@ -26,6 +26,7 @@ #include "ViewProviderDocumentObject.h" +#include "ViewProviderPythonFeature.h" namespace Gui { @@ -63,6 +64,7 @@ private: std::vector nodes; }; +typedef ViewProviderPythonFeatureT ViewProviderDocumentObjectGroupPython; } // namespace Gui diff --git a/src/Mod/Arch/ArchBuilding.py b/src/Mod/Arch/ArchBuilding.py index 96f1bc067..6a2cb2c33 100644 --- a/src/Mod/Arch/ArchBuilding.py +++ b/src/Mod/Arch/ArchBuilding.py @@ -21,7 +21,7 @@ #* * #*************************************************************************** -import ArchCell,FreeCAD,FreeCADGui,Draft,ArchCommands +import FreeCAD,FreeCADGui,Draft,ArchCommands from PyQt4 import QtCore __title__="FreeCAD Building" @@ -31,14 +31,11 @@ __url__ = "http://free-cad.sourceforge.net" def makeBuilding(objectslist=None,join=False,name="Building"): '''makeBuilding(objectslist,[joinmode]): creates a building including the objects from the given list. If joinmode is True, components will be joined.''' - obj = FreeCAD.ActiveDocument.addObject("Part::FeaturePython",name) + obj = FreeCAD.ActiveDocument.addObject("App::DocumentObjectGroupPython",name) _Building(obj) _ViewProviderBuilding(obj.ViewObject) if objectslist: - obj.Components = objectslist - for comp in obj.Components: - comp.ViewObject.hide() - obj.JoinMode = join + obj.Group = objectslist return obj class _CommandBuilding: @@ -66,18 +63,32 @@ class _CommandBuilding: FreeCAD.ActiveDocument.commitTransaction() FreeCAD.ActiveDocument.recompute() -class _Building(ArchCell._Cell): +class _Building: "The Building object" def __init__(self,obj): - ArchCell._Cell.__init__(self,obj) self.Type = "Building" + obj.Proxy = self + + def execute(self,obj): + pass -class _ViewProviderBuilding(ArchCell._ViewProviderCell): + def onChanged(self,obj,prop): + pass + +class _ViewProviderBuilding: "A View Provider for the Building object" def __init__(self,vobj): - ArchCell._ViewProviderCell.__init__(self,vobj) + vobj.Proxy = self def getIcon(self): return ":/icons/Arch_Building_Tree.svg" + def attach(self,vobj): + self.Object = vobj.Object + return + + def claimChildren(self): + return self.Object.Group + + FreeCADGui.addCommand('Arch_Building',_CommandBuilding()) diff --git a/src/Mod/Arch/ArchCommands.py b/src/Mod/Arch/ArchCommands.py index b25d0c68f..5c9a75713 100644 --- a/src/Mod/Arch/ArchCommands.py +++ b/src/Mod/Arch/ArchCommands.py @@ -39,12 +39,18 @@ def addComponents(objectsList,host): if not isinstance(objectsList,list): objectsList = [objectsList] tp = Draft.getType(host) - if tp in ["Cell","Floor","Building","Site"]: + if tp in ["Cell"]: c = host.Components for o in objectsList: if not o in c: c.append(o) host.Components = c + elif tp in ["Floor","Building","Site"]: + c = host.Group + for o in objectsList: + if not o in c: + c.append(o) + host.Group = c elif tp in ["Wall","Structure"]: a = host.Additions for o in objectsList: diff --git a/src/Mod/Arch/ArchFloor.py b/src/Mod/Arch/ArchFloor.py index 4e17d1660..f5b9d435e 100644 --- a/src/Mod/Arch/ArchFloor.py +++ b/src/Mod/Arch/ArchFloor.py @@ -21,7 +21,7 @@ #* * #*************************************************************************** -import ArchCell,FreeCAD,FreeCADGui,Draft,ArchCommands +import FreeCAD,FreeCADGui,Draft,ArchCommands from PyQt4 import QtCore __title__="FreeCAD Arch Floor" @@ -32,14 +32,11 @@ def makeFloor(objectslist=None,join=True,name="Floor"): '''makeFloor(objectslist,[joinmode]): creates a floor including the objects from the given list. If joinmode is False, components will not be joined.''' - obj = FreeCAD.ActiveDocument.addObject("Part::FeaturePython",name) + obj = FreeCAD.ActiveDocument.addObject("App::DocumentObjectGroupPython",name) _Floor(obj) _ViewProviderFloor(obj.ViewObject) if objectslist: - obj.Components = objectslist - for comp in obj.Components: - comp.ViewObject.hide() - obj.JoinMode = join + obj.Group = objectslist return obj class _CommandFloor: @@ -67,20 +64,34 @@ class _CommandFloor: FreeCAD.ActiveDocument.commitTransaction() FreeCAD.ActiveDocument.recompute() -class _Floor(ArchCell._Cell): +class _Floor: "The Cell object" def __init__(self,obj): - ArchCell._Cell.__init__(self,obj) obj.addProperty("App::PropertyLength","Height","Base", "The height of this floor") self.Type = "Floor" + obj.Proxy = self + + def execute(self,obj): + pass -class _ViewProviderFloor(ArchCell._ViewProviderCell): + def onChanged(self,obj,prop): + pass + + +class _ViewProviderFloor: "A View Provider for the Cell object" def __init__(self,vobj): - ArchCell._ViewProviderCell.__init__(self,vobj) + vobj.Proxy = self def getIcon(self): return ":/icons/Arch_Floor_Tree.svg" + def attach(self,vobj): + self.Object = vobj.Object + return + + def claimChildren(self): + return self.Object.Group + FreeCADGui.addCommand('Arch_Floor',_CommandFloor()) diff --git a/src/Mod/Arch/ArchSectionPlane.py b/src/Mod/Arch/ArchSectionPlane.py index 50cc067bf..04a8fb1d3 100644 --- a/src/Mod/Arch/ArchSectionPlane.py +++ b/src/Mod/Arch/ArchSectionPlane.py @@ -157,9 +157,11 @@ class _ViewProviderSectionPlane(ArchComponent.ViewProviderComponent): class _ArchDrawingView: def __init__(self, obj): obj.addProperty("App::PropertyLink","Source","Base","The linked object") - obj.addProperty("App::PropertyEnumeration","RenderingMode","Base","The rendering mode to use") + obj.addProperty("App::PropertyEnumeration","RenderingMode","Drawing View","The rendering mode to use") + obj.addProperty("App::PropertyFloat","LineWidth","Drawing View","The line width of the rendered objects") obj.RenderingMode = ["Solid","Wireframe"] obj.RenderingMode = "Solid" + obj.LineWidth = 0.35 obj.Proxy = self self.Type = "DrawingView" @@ -179,28 +181,35 @@ class _ArchDrawingView: if obj.Source.Objects: svg = '' cp = ArchCommands.getCutVolume(obj.Source.Objects,obj.Source.Placement) - print "cp:",cp - sections = [] + self.sections = [] if cp: cutvolume = cp[0].extrude(cp[1]) shapes = [] + colors = [] for o in obj.Source.Objects: + color = o.ViewObject.DiffuseColor[0] + print "adding ",o.Name," with color ",color if cp: - shapes.append(o.Shape.cut(cutvolume)) + for s in o.Shape.Solids: + shapes.append(s.cut(cutvolume)) + colors.append(color) sec = o.Shape.section(cp[0]) if sec.Edges: - sec = Part.Wire(fcgeo.sortEdges(sec.Edges)) - sec = Part.Face(sec) - sections.append(sec) + wires = fcgeo.findWires(sec.Edges) + for w in wires: + sec = Part.Wire(fcgeo.sortEdges(w.Edges)) + sec = Part.Face(sec) + self.sections.append(sec) else: shapes.append(o.Shape) + colors.append(color) + linewidth = obj.LineWidth/obj.Scale if obj.RenderingMode == "Solid": - svg += self.renderVRM(shapes,obj.Source.Placement) + svg += self.renderVRM(shapes,obj.Source.Placement,colors,linewidth) else: - svg += self.renderOCC(shapes,obj.Source.Proxy.getNormal(obj.Source)) - print "sections:",sections - for s in sections: - svg += self.renderSection(s,obj.Source.Placement) + svg += self.renderOCC(shapes,obj.Source.Proxy.getNormal(obj.Source),linewidth) + for s in self.sections: + svg += self.renderSection(s,obj.Source.Placement,linewidth*2) result = '' result += ' - + - + - if this is checked, the internal Arch IFC parser will be use to build Arch objects from known IFC types. + If this is checked, the IFCOpenShell importer will be used, allowing to import more IFC types - use internal IFC parser - - - true + Use IFCOpenShell if available - useIfcParser + useIfcOpenShell Mod/Arch @@ -188,17 +185,34 @@ - + - + - If this is checked, the IFCOpenShell importer will be used for objects not handled by the internal parser + Creates groups for each Arch object type - Use IFCOpenShell + Group components by types - useIfcOpenShell + createIfcGroups + + + Mod/Arch + + + + + + + + + + + Import furniture (can make the model heavy) + + + importIfcFurniture Mod/Arch diff --git a/src/Mod/Arch/importIFC.py b/src/Mod/Arch/importIFC.py index 56d379413..87dd09796 100644 --- a/src/Mod/Arch/importIFC.py +++ b/src/Mod/Arch/importIFC.py @@ -21,16 +21,18 @@ #* * #*************************************************************************** -import ifcReader, FreeCAD, Arch, Draft, os, sys, time, tempfile, Part +import ifcReader, FreeCAD, Arch, Draft, os, sys, time, Part from draftlibs import fcvec __title__="FreeCAD IFC importer" __author__ = "Yorik van Havre" __url__ = "http://free-cad.sourceforge.net" +# config DEBUG = True SCHEMA = "http://www.steptools.com/support/stdev_docs/express/ifc2x3/ifc2x3_tc1.exp" -SKIP = ["IfcOpeningElement"] +SKIP = ["IfcOpeningElement","IfcSpace"] +# end config if open.__module__ == '__builtin__': pyopen = open # because we'll redefine open below @@ -41,13 +43,15 @@ def open(filename): doc = FreeCAD.newDocument(docname) doc.Label = decode(docname) FreeCAD.ActiveDocument = doc + global createIfcGroups, useIfcOpenShell, importIfcFurniture + createIfcGroups = useIfcOpenShell = importIfcFurniture = False p = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Arch") - op = p.GetBool("useIfcOpenShell") - ip = p.GetBool("useIfcParser") - if op: - readOpenShell(filename,useParser=ip) - else: - readInternal(filename) + useIfcOpenShell = p.GetBool("useIfcOpenShell") + createIfcGroups = p.GetBool("createIfcGroups") + importIfcFurniture = p.GetBool("importIfcFurniture") + if not importIfcFurniture: + SKIP.append("IfcFurnishingElement") + read(filename) return doc def decode(name): @@ -85,47 +89,72 @@ def getIfcOpenShell(): else: return True -def readOpenShell(filename,useParser=False): +def read(filename): "Parses an IFC file with IfcOpenShell" - altifc = None - if useParser: - altifc = parseFile(filename) + # parsing the IFC file + t1 = time.time() + schema=getSchema() + if schema: + if DEBUG: global ifc + if DEBUG: print "opening",filename,"..." + ifc = ifcReader.IfcDocument(filename,schema=schema,debug=DEBUG) + else: + FreeCAD.Console.PrintWarning("IFC Schema not found, IFC import disabled.\n") + return None + t2 = time.time() + if DEBUG: print "Successfully loaded",ifc,"in %s s" % ((t2-t1)) - if getIfcOpenShell(): - USESHAPES = False + if useIfcOpenShell and getIfcOpenShell(): + # use the IfcOpenShell parser + + useShapes = False if hasattr(IfcImport,"USE_BREP_DATA"): IfcImport.Settings(IfcImport.USE_BREP_DATA,True) - USESHAPES = True + useShapes = True if IfcImport.Init(filename): while True: obj = IfcImport.Get() if DEBUG: print "parsing ",obj.id,": ",obj.name," of type ",obj.type meshdata = [] - n = obj.name - if not n: n = "Unnamed" + # retrieving name + n = obj.name + if not n: + n = "Unnamed" + + # build shape + shape = None + if useShapes: + shape = getShape(obj) + + # skip types if obj.type in SKIP: pass # walls - elif altifc and (obj.type == "IfcWallStandardCase"): - makeWall(altifc.Entities[obj.id],shape = getShape(obj) if USESHAPES else None) + elif obj.type == "IfcWallStandardCase": + makeWall(ifc.Entities[obj.id],shape) # windows - elif altifc and (obj.type in ["IfcWindow","IfcDoor"]): - makeWindow(altifc.Entities[obj.id],shape = getShape(obj) if USESHAPES else None) + elif obj.type in ["IfcWindow","IfcDoor"]: + makeWindow(ifc.Entities[obj.id],shape) # structs - elif altifc and (obj.type in ["IfcBeam","IfcColumn","IfcSlab"]): - makeStructure(altifc.Entities[obj.id],shape = getShape(obj) if USESHAPES else None) + elif obj.type in ["IfcBeam","IfcColumn","IfcSlab"]: + makeStructure(ifc.Entities[obj.id],shape) + + # furniture + elif obj.type == "IfcFurnishingElement": + nobj = FreeCAD.ActiveDocument.addObject("Part::Feature","Furniture") + nobj.Shape = shape - elif USESHAPES: - # treat as Parts - sh = getShape(obj) + elif shape: + # treat as dumb parts nobj = FreeCAD.ActiveDocument.addObject("Part::Feature",n) - nobj.Shape = sh + nobj.Shape = shape + else: # treat as meshes me,pl = getMesh(obj) @@ -135,59 +164,49 @@ def readOpenShell(filename,useParser=False): if not IfcImport.Next(): break - if altifc: - order(altifc) - IfcImport.CleanUp() - return None - -def readInternal(filename): - "processes an ifc file and add its objects to the given document" - t1 = time.time() - ifc = parseFile(filename) - t2 = time.time() - if DEBUG: print "Successfully loaded",ifc,"in %s s" % ((t2-t1)) - # getting walls - for w in ifc.getEnt("IFCWALLSTANDARDCASE"): - makeWall(w) - # getting windows and doors - for w in (ifc.getEnt("IFCWINDOW") + ifc.getEnt("IFCDOOR")): - makeWindow(w) - # getting structs - for w in (ifc.getEnt("IFCSLAB") + ifc.getEnt("IFCBEAM") + ifc.getEnt("IFCCOLUMN")): - makeWindow(w) + + IfcImport.CleanUp() + + else: + # use the internal python parser + + # getting walls + for w in ifc.getEnt("IfcWallStandardCase"): + makeWall(w) + + # getting windows and doors + for w in (ifc.getEnt("IfcWindow") + ifc.getEnt("IfcDoor")): + makeWindow(w) + + # getting structs + for w in (ifc.getEnt("IfcSlab") + ifc.getEnt("IfcBeam") + ifc.getEnt("IfcColumn")): + makeStructure(w) + order(ifc) FreeCAD.ActiveDocument.recompute() t3 = time.time() if DEBUG: print "done processing",ifc,"in %s s" % ((t3-t1)) - + + return None + def order(ifc): "orders the already generated elements by building and by floor" + # getting floors - for f in ifc.getEnt("IFCBUILDINGSTOREY"): - makeCell(f,"Floor") + for f in ifc.getEnt("IfcBuildingStorey"): + group(f,"Floor") # getting buildings - for b in ifc.getEnt("IFCBUILDING"): - makeCell(b,"Building") + for b in ifc.getEnt("IfcBuilding"): + group(b,"Building") # getting sites - for s in ifc.getEnt("IFCSITE"): - makeCell(s,"Site") + for s in ifc.getEnt("IfcSite"): + group(s,"Site") -def parseFile(filename): - "parses an IFC file" - schema=getSchema() - if schema: - if DEBUG: global ifc - if DEBUG: print "opening",filename,"..." - ifc = ifcReader.IfcDocument(filename,schema=schema,debug=DEBUG) - return ifc - else: - FreeCAD.Console.PrintWarning("IFC Schema not found, IFC import disabled.\n") - return None - -def makeCell(entity,mode="Cell"): - "makes a cell in the freecad document" +def group(entity,mode=None): + "gathers the children of the given entity" + try: - if DEBUG: print "=====> making cell",entity.id + if DEBUG: print "=====> making group",entity.id placement = None placement = getPlacement(entity.ObjectPlacement) if DEBUG: print "got cell placement",entity.id,":",placement @@ -208,37 +227,50 @@ def makeCell(entity,mode="Cell"): if not isinstance(s,list): s = [s] elts.extend(s) print "found dependent elements: ",elts - fcelts = [] + + groups = [['Wall','IfcWallStandardCase',[]], + ['Window','IfcWindow',[]], + ['Door','IfcDoor',[]], + ['Slab','IfcSlab',[]], + ['Beam','IfcBeam',[]], + ['Column','IfcColumn',[]], + ['Floor','IfcBuildingStorey',[]], + ['Building','IfcBuilding',[]], + ['Furniture','IfcFurnishingElement',[]]] + for e in elts: - if e.type == "IFCWALLSTANDARDCASE": - o = FreeCAD.ActiveDocument.getObject("Wall"+str(e.id)) - elif e.type == "IFCWINDOW": - o = FreeCAD.ActiveDocument.getObject("Window"+str(e.id)) - elif e.type == "IFCDOOR": - o = FreeCAD.ActiveDocument.getObject("Door"+str(e.id)) - elif e.type == "IFCSLAB": - o = FreeCAD.ActiveDocument.getObject("Slab"+str(e.id)) - elif e.type == "IFCBEAM": - o = FreeCAD.ActiveDocument.getObject("Beam"+str(e.id)) - elif e.type == "IFCCOLUMN": - o = FreeCAD.ActiveDocument.getObject("Column"+str(e.id)) - elif e.type == "IFCBUILDINGSTOREY": - o = FreeCAD.ActiveDocument.getObject("Floor"+str(e.id)) - elif e.type == "IFCBUILDING": - o = FreeCAD.ActiveDocument.getObject("Building"+str(e.id)) - if o: - fcelts.append(o) - name = mode+str(entity.id) - if mode == "Site": - cell = Arch.makeSite(fcelts,name=name) - elif mode == "Floor": - cell = Arch.makeFloor(fcelts,join=False,name=name) - elif mode == "Building": - cell = Arch.makeBuilding(fcelts,name=name) + for g in groups: + if e.type.upper() == g[1].upper(): + o = FreeCAD.ActiveDocument.getObject(g[0] + str(e.id)) + if o: + g[2].append(o) + print "groups:",groups + + comps = [] + if createIfcGroups: + if DEBUG: print "creating subgroups" + for g in groups: + if g[2]: + if g[0] in ['Building','Floor']: + comps.extend(g[2]) + else: + fcg = FreeCAD.ActiveDocument.addObject("App::DocumentObjectGroup",g[0]+"s") + for o in g[2]: + fcg.addObject(o) + comps.append(fcg) else: - cell = Arch.makeCell(fcelts,join=False,name=name) + for g in groups: + comps.extend(g[2]) + + name = mode + str(entity.id) + if mode == "Site": + cell = Arch.makeSite(comps,name=name) + elif mode == "Floor": + cell = Arch.makeFloor(comps,name=name) + elif mode == "Building": + cell = Arch.makeBuilding(comps,name=name) except: - if DEBUG: print "error: skipping cell",entity.id + if DEBUG: print "error: skipping group ",entity.id def makeWall(entity,shape=None): "makes a wall in the freecad document" diff --git a/src/Mod/Draft/Draft.py b/src/Mod/Draft/Draft.py index 772bcbf98..853385fc8 100644 --- a/src/Mod/Draft/Draft.py +++ b/src/Mod/Draft/Draft.py @@ -171,6 +171,16 @@ def getType(obj): return "Group" return "Unknown" +def get3DView(): + "get3DView(): returns the current view if it is 3D, or the first 3D view found, or None" + v = FreeCADGui.ActiveDocument.ActiveView + if str(type(v)) == "": + return v + v = FreeCADGui.ActiveDocument.mdiViewsOfType("Gui::View3DInventor") + if v: + return v[0] + return None + def isClone(obj,objtype): """isClone(obj,objtype): returns True if the given object is a clone of an object of the given type""" @@ -1172,21 +1182,17 @@ def draftify(objectslist,makeblock=False): return newobjlist[0] return newobjlist -def getSVG(obj,modifier=100,textmodifier=100,fillstyle="shape color",direction=None): - '''getSVG(object,[modifier],[textmodifier],[fillstyle],[direction]): - returns a string containing a SVG representation of the given object. the modifier attribute - specifies a scale factor for linewidths in %, and textmodifier specifies - a scale factor for texts, in % (both default = 100). You can also supply - an arbitrary projection vector.''' +def getSVG(obj,scale=1,linewidth=0.35,fontsize=12,fillstyle="shape color",direction=None): + '''getSVG(object,[scale], [linewidth],[fontsize],[fillstyle],[direction]): + returns a string containing a SVG representation of the given object, + with the given linewidth and fontsize (used if the given object contains + any text). You can also supply an arbitrary projection vector. the + scale parameter allows to scale linewidths down, so they are resolution-independant.''' import Part from draftlibs import fcgeo svg = "" - tmod = ((textmodifier-100)/2)+100 - if tmod == 0: tmod = 0.01 - modifier = 200-modifier - if modifier == 0: modifier = 0.01 - pmod = (200-textmodifier)/20 - if pmod == 0: pmod = 0.01 + linewidth = linewidth/scale + fontsize = (fontsize/scale)/2 plane = None if direction: if direction != Vector(0,0,0): @@ -1259,8 +1265,8 @@ def getSVG(obj,modifier=100,textmodifier=100,fillstyle="shape color",direction=N if fill != 'none': svg += 'Z' svg += '" ' svg += 'stroke="' + stroke + '" ' - svg += 'stroke-width="' + str(width) + ' px" ' - svg += 'style="stroke-width:'+ str(width) + svg += 'stroke-width="' + str(linewidth) + ' px" ' + svg += 'style="stroke-width:'+ str(linewidth) svg += ';stroke-miterlimit:4' svg += ';stroke-dasharray:' + lstyle svg += ';fill:' + fill + '"' @@ -1274,8 +1280,8 @@ def getSVG(obj,modifier=100,textmodifier=100,fillstyle="shape color",direction=N svg += '" cy="' + str(cen.y) svg += '" r="' + str(rad)+'" ' svg += 'stroke="' + stroke + '" ' - svg += 'stroke-width="' + str(width) + ' px" ' - svg += 'style="stroke-width:'+ str(width) + svg += 'stroke-width="' + str(linewidth) + ' px" ' + svg += 'style="stroke-width:'+ str(linewidth) svg += ';stroke-miterlimit:4' svg += ';stroke-dasharray:' + lstyle svg += ';fill:' + fill + '"' @@ -1319,35 +1325,36 @@ def getSVG(obj,modifier=100,textmodifier=100,fillstyle="shape color",direction=N svg += 'L '+str(p4.x)+' '+str(p4.y)+'" ' svg += 'fill="none" stroke="' svg += getrgb(obj.ViewObject.LineColor) + '" ' - svg += 'stroke-width="' + str(obj.ViewObject.LineWidth/modifier) + ' px" ' - svg += 'style="stroke-width:'+ str(obj.ViewObject.LineWidth/modifier) + svg += 'stroke-width="' + str(linewidth) + ' px" ' + svg += 'style="stroke-width:'+ str(linewidth) svg += ';stroke-miterlimit:4;stroke-dasharray:none" ' svg += 'freecad:basepoint1="'+str(p1.x)+' '+str(p1.y)+'" ' svg += 'freecad:basepoint2="'+str(p4.x)+' '+str(p4.y)+'" ' svg += 'freecad:dimpoint="'+str(p2.x)+' '+str(p2.y)+'"' svg += '/>\n' svg += '\n' + #svg +='scale('+str(tmod/2000)+','+str(-tmod/2000)+')' + svg += 'scale(1,-1) ' + svg += '">\n' for l in obj.LabelText: svg += ''+l+'\n' svg += '\n' @@ -1378,7 +1387,6 @@ def getSVG(obj,modifier=100,textmodifier=100,fillstyle="shape color",direction=N lorig = getLineStyle(obj) name = obj.Name stroke = getrgb(obj.ViewObject.LineColor) - width = obj.ViewObject.LineWidth/modifier fill = 'none' invpl = obj.Placement.inverse() n = 0 @@ -1422,7 +1430,6 @@ def getSVG(obj,modifier=100,textmodifier=100,fillstyle="shape color",direction=N stroke = "none" else: stroke = getrgb(obj.ViewObject.LineColor) - width = obj.ViewObject.LineWidth/modifier if len(obj.Shape.Vertexes) > 1: wiredEdges = [] @@ -1794,12 +1801,12 @@ class _ViewProviderDimension: if not proj: norm = Vector(0,0,1) else: norm = fcvec.neg(p3.sub(p2).cross(proj)) norm.normalize() - va = FreeCADGui.ActiveDocument.ActiveView.getViewDirection() + va = get3DView().getViewDirection() if va.getAngle(norm) < math.pi/2: norm = fcvec.neg(norm) u = p3.sub(p2) u.normalize() - c = FreeCADGui.ActiveDocument.ActiveView.getCameraNode() + c = get3DView().getCameraNode() r = c.orientation.getValue() ru = Vector(r.multVec(coin.SbVec3f(1,0,0)).getValue()) if ru.getAngle(u) > math.pi/2: u = fcvec.neg(u) @@ -2511,19 +2518,18 @@ class _Polygon: class _DrawingView: def __init__(self, obj): - obj.addProperty("App::PropertyVector","Direction","Shape view","Projection direction") - obj.addProperty("App::PropertyFloat","LinewidthModifier","Drawing view","Modifies the linewidth of the lines inside this object") - obj.addProperty("App::PropertyFloat","TextModifier","Drawing view","Modifies the size of the texts inside this object") + obj.addProperty("App::PropertyVector","Direction","Shape View","Projection direction") + obj.addProperty("App::PropertyFloat","LineWidth","Drawing View","The width of the lines inside this object") + obj.addProperty("App::PropertyFloat","FontSize","Drawing View","The size of the texts inside this object") obj.addProperty("App::PropertyLink","Source","Base","The linked object") - obj.addProperty("App::PropertyEnumeration","FillStyle","Drawing view","Shape Fill Style") + obj.addProperty("App::PropertyEnumeration","FillStyle","Drawing View","Shape Fill Style") fills = ['shape color'] for f in FreeCAD.svgpatterns.keys(): fills.append(f) obj.FillStyle = fills - obj.Proxy = self - obj.LinewidthModifier = 100 - obj.TextModifier = 100 + obj.LineWidth = 0.35 + obj.FontSize = 12 self.Type = "DrawingView" def execute(self, obj): @@ -2531,12 +2537,12 @@ class _DrawingView: obj.ViewResult = self.updateSVG(obj) def onChanged(self, obj, prop): - if prop in ["X","Y","Scale","LinewidthModifier","TextModifier","FillStyle","Direction"]: + if prop in ["X","Y","Scale","LineWidth","FontSize","FillStyle","Direction"]: obj.ViewResult = self.updateSVG(obj) def updateSVG(self, obj): "encapsulates a svg fragment into a transformation node" - svg = getSVG(obj.Source,obj.LinewidthModifier,obj.TextModifier,obj.FillStyle,obj.Direction) + svg = getSVG(obj.Source,obj.Scale,obj.LineWidth,obj.FontSize,obj.FillStyle,obj.Direction) result = '' result += '" << endl; diff --git a/src/Mod/Drawing/App/FeatureViewPart.h b/src/Mod/Drawing/App/FeatureViewPart.h index 466cad207..68ad3551f 100644 --- a/src/Mod/Drawing/App/FeatureViewPart.h +++ b/src/Mod/Drawing/App/FeatureViewPart.h @@ -52,6 +52,7 @@ public: App::PropertyVector Direction; App::PropertyBool ShowHiddenLines; App::PropertyBool ShowSmoothLines; + App::PropertyFloat LineWidth; /** @name methods overide Feature */ diff --git a/src/Mod/Drawing/App/ProjectionAlgos.cpp b/src/Mod/Drawing/App/ProjectionAlgos.cpp index cb82c3e8e..a5f844619 100644 --- a/src/Mod/Drawing/App/ProjectionAlgos.cpp +++ b/src/Mod/Drawing/App/ProjectionAlgos.cpp @@ -153,8 +153,10 @@ std::string ProjectionAlgos::getSVG(SvgExtractionType type, float scale) { std::stringstream result; SVGOutput output; + float hfactor = 0.5f; // hidden line size factor, was 0.15f / 0.35f; + if (!H.IsNull() && (type & WithHidden)) { - float width = 0.15f/scale; + float width = hfactor * scale; BRepMesh::Mesh(H,0.1); result << "" << endl << output.exportEdges(H) << "" << endl; } if (!HO.IsNull() && (type & WithHidden)) { - float width = 0.15f/scale; + float width = hfactor * scale; BRepMesh::Mesh(HO,0.1); result << "" << endl << output.exportEdges(HO) << "" << endl; } if (!VO.IsNull()) { - float width = 0.35f/scale; + float width = scale; BRepMesh::Mesh(VO,0.1); result << "" << endl; } if (!V.IsNull()) { - float width = 0.35f/scale; + float width = scale; BRepMesh::Mesh(V,0.1); result << "" << endl; } if (!V1.IsNull() && (type & WithSmooth)) { - float width = 0.35f/scale; + float width = scale; BRepMesh::Mesh(V1,0.1); result << "" << endl; } if (!H1.IsNull() && (type & WithSmooth) && (type & WithHidden)) { - float width = 0.15f/scale; + float width = hfactor * scale; BRepMesh::Mesh(H1,0.1); result << "" << endl << output.exportEdges(H1) diff --git a/src/Mod/Sketcher/Gui/CommandCreateGeo.cpp b/src/Mod/Sketcher/Gui/CommandCreateGeo.cpp index 89685e99a..02e508e76 100644 --- a/src/Mod/Sketcher/Gui/CommandCreateGeo.cpp +++ b/src/Mod/Sketcher/Gui/CommandCreateGeo.cpp @@ -621,7 +621,7 @@ public: if (geom->getTypeId() == Part::GeomLineSegment::getClassTypeId()) { const Part::GeomLineSegment *lineSeg = dynamic_cast(geom); EditCurve[0] = Base::Vector2D(lineSeg->getEndPoint().x, lineSeg->getEndPoint().y); - } + } else EditCurve[0] = onSketchPos; @@ -1365,7 +1365,7 @@ CmdSketcherCreateFillet::CmdSketcherCreateFillet() sAppModule = "Sketcher"; sGroup = QT_TR_NOOP("Sketcher"); sMenuText = QT_TR_NOOP("Create fillet"); - sToolTipText = QT_TR_NOOP("Create a fillet between to lines or at a coincident point"); + sToolTipText = QT_TR_NOOP("Create a fillet between two lines or at a coincidental point"); sWhatsThis = sToolTipText; sStatusTip = sToolTipText; sPixmap = "Sketcher_CreateFillet"; diff --git a/src/WindowsInstaller/LibPack.wxs b/src/WindowsInstaller/LibPack.wxs index 37b4da8ce..612146892 100644 --- a/src/WindowsInstaller/LibPack.wxs +++ b/src/WindowsInstaller/LibPack.wxs @@ -99,7 +99,6 @@ -