diff --git a/src/Mod/Arch/SectionPlane.py b/src/Mod/Arch/SectionPlane.py index 74f8f07c5..cf18ca1cf 100644 --- a/src/Mod/Arch/SectionPlane.py +++ b/src/Mod/Arch/SectionPlane.py @@ -1,7 +1,9 @@ -import FreeCAD,FreeCADGui,Part,Component +import FreeCAD,FreeCADGui,Part,Component,WorkingPlane,Drawing,math from FreeCAD import Vector from PyQt4 import QtCore from pivy import coin +from draftlibs import fcvec,fcgeo + class CommandSectionPlane: "the Arch SectionPlane command definition" @@ -11,18 +13,37 @@ class CommandSectionPlane: 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Arch_SectionPlane","Adds a section plane object to the document")} def Activated(self): + sel = FreeCADGui.Selection.getSelection() FreeCAD.ActiveDocument.openTransaction("Section Plane") obj = FreeCAD.ActiveDocument.addObject("Part::FeaturePython","Section") SectionPlane(obj) ViewProviderSectionPlane(obj.ViewObject) FreeCAD.ActiveDocument.commitTransaction() + g = [] + for o in sel: + if o.isDerivedFrom("Part::Feature"): + g.append(o) + obj.Objects = g + page = FreeCAD.ActiveDocument.addObject("Drawing::FeaturePage","Page") + template = FreeCAD.getResourceDir()+'Mod/Drawing/Templates/A3_Landscape.svg' + page.ViewObject.HintOffsetX = 200 + page.ViewObject.HintOffsetY = 100 + page.ViewObject.HintScale = 20 + page.Template = template + view = FreeCAD.ActiveDocument.addObject("Drawing::FeatureViewPython","View") + page.addObject(view) + ArchDrawingView(view) + view.Source = obj FreeCAD.ActiveDocument.recompute() class SectionPlane: "A section plane object" def __init__(self,obj): obj.Proxy = self - self.Type = "Visual Component" + obj.addProperty("App::PropertyLinkList","Objects","Base", + "The objects that must be considered by this section plane. Empty means all document") + self.Type = "Section" + self.Object = obj def execute(self,obj): pl = obj.Placement @@ -30,6 +51,13 @@ class SectionPlane: p = Part.makePlane(l,l,Vector(l/2,-l/2,0),Vector(0,0,-1)) obj.Shape = p obj.Placement = pl + self.Object = obj + + def onChanged(self,obj,prop): + pass + + def getNormal(self): + return fcvec.neg(self.Object.Shape.Faces[0].normalAt(0,0)) class ViewProviderSectionPlane(Component.ViewProviderComponent): "A View Provider for Section Planes" @@ -124,4 +152,225 @@ class ViewProviderSectionPlane(Component.ViewProviderComponent): vobj.Object.Proxy.execute(vobj.Object) return +class ArchDrawingView: + def __init__(self, obj): + obj.addProperty("App::PropertyLink","Source","Base","The linked object") + obj.Proxy = self + self.Type = "DrawingView" + + def execute(self, obj): + print "executing" + if obj.Source: + obj.ViewResult = self.updateSVG(obj) + + def onChanged(self, obj, prop): + print "prop:",prop + if prop == "Source": + obj.ViewResult = self.updateSVG(obj) + + def updateSVG(self, obj): + "encapsulates a svg fragment into a transformation node" + if obj.Source: + if obj.Source.Objects: + svg = '' + for o in obj.Source.Objects: + svg += self.getSVG(o,obj.Source.Proxy.getNormal()) + result = '' + result += ' 1: + l = -l + return fcvec.scaleTo(p2.sub(p1),l) + + def getFirstIndex(list1,list2): + "returns the first index from list2 where there is an item of list1" + for i1 in range(len(list1)): + for i2 in range(len(list2)): + if list1[i1].hashCode() == list2[i2].hashCode(): + return i2 + return None + + def getLastIndex(list1,list2): + "returns the last index from list2 where there is an item of list1" + i = None + for i1 in range(len(list1)): + for i2 in range(len(list2)): + if list1[i1].hashCode() == list2[i2].hashCode(): + i = i2 + return i + + def getProj(vec): + if not plane: + return vec + nx = fcvec.project(vec,plane.u) + lx = nx.Length + if abs(nx.getAngle(plane.u)) > 0.1: lx = -lx + ny = fcvec.project(vec,plane.v) + ly = ny.Length + if abs(ny.getAngle(plane.v)) > 0.1: ly = -ly + return Vector(lx,ly,0) + + def getPath(face): + svg =' 1: + z = -z + + print "face center:",center," ray:",ray + + tempFaces = [face] + + # comparing with other faces crossed by the same ray + for of in unsortedFaces: + obb = of.BoundBox + op = intersection(base,ray,of.CenterOfMass,of.normalAt(0,0)) + if obb.isInside(op): + oray = op.sub(base) + oray = fcvec.project(oray,direction) + oz = oray.Length + if oray.getAngle(direction) > 1: + oz = -oz + if oz > 0: + if oz < z: + tempFaces.insert(0,of) + elif oz > z: + tempFaces.append(of) + + print "tempFaces:",tempFaces + + # finding the position of the base face among others + findex = 0 + if len(tempFaces) > 1: + for i in range(len(tempFaces)): + if tempFaces[i].hashCode() == bhash: + findex = i + + print "face index in tempfaces:",findex + + # finding the right place to insert in ordered list + oindex = 0 + if not sortedFaces: + sortedFaces.append(face) + elif len(tempFaces) == 1: + sortedFaces.append(face) + else: + if findex == 0: # our face is the first item + ni = getFirstIndex(tempFaces[1:],sortedFaces) + if ni == None: + sortedFaces.append(face) + else: + sortedFaces.insert(ni,face) + elif findex == len(tempFaces)-1: # our face is the last item + ni = getLastIndex(tempFaces[:-1],sortedFaces) + if ni == None: + sortedFaces.append(face) + else: + sortedFaces.insert(ni+1,face) + else: # there are faces before and after + i1 = getLastIndex(tempFaces[:findex],sortedFaces) + i2 = getFirstIndex(tempFaces[findex+1:],sortedFaces) + if i1 == None: + if i2 == None: + sortedFaces.append(face) + else: + sortedFaces.insert(i2,face) + else: + sortedFaces.insert(i1+1,face) + + print "sorted faces:",len(sortedFaces) + + # building SVG representation + svg = '' + for f in sortedFaces: + svg += getPath(f) + + print "result:",svg + + return svg + + FreeCADGui.addCommand('Arch_SectionPlane',CommandSectionPlane())