Wall.py

Go to the documentation of this file.
00001 #***************************************************************************
00002 #*                                                                         *
00003 #*   Copyright (c) 2011                                                    *  
00004 #*   Yorik van Havre <yorik@uncreated.net>                                 *  
00005 #*                                                                         *
00006 #*   This program is free software; you can redistribute it and/or modify  *
00007 #*   it under the terms of the GNU General Public License (GPL)            *
00008 #*   as published by the Free Software Foundation; either version 2 of     *
00009 #*   the License, or (at your option) any later version.                   *
00010 #*   for detail see the LICENCE text file.                                 *
00011 #*                                                                         *
00012 #*   This program is distributed in the hope that it will be useful,       *
00013 #*   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00014 #*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00015 #*   GNU Library General Public License for more details.                  *
00016 #*                                                                         *
00017 #*   You should have received a copy of the GNU Library General Public     *
00018 #*   License along with this program; if not, write to the Free Software   *
00019 #*   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  *
00020 #*   USA                                                                   *
00021 #*                                                                         *
00022 #***************************************************************************
00023 
00024 import FreeCAD,FreeCADGui,Part,Draft,Component
00025 from draftlibs import fcgeo,fcvec
00026 from FreeCAD import Vector
00027 from PyQt4 import QtCore
00028 
00029 __title__="FreeCAD Wall"
00030 __author__ = "Yorik van Havre"
00031 __url__ = "http://free-cad.sourceforge.net"
00032 
00033 def makeWall(baseobj=None,width=None,height=None,align="Center",name="Wall"):
00034     '''makeWall(obj,[width],[height],[align],[name]): creates a wall based on the
00035     given object'''
00036     obj = FreeCAD.ActiveDocument.addObject("Part::FeaturePython",name)
00037     Wall(obj)
00038     ViewProviderWall(obj.ViewObject)
00039     if baseobj: obj.Base = baseobj
00040     if width: obj.Width = width
00041     if height: obj.Height = height
00042     obj.Align = align
00043     if obj.Base: obj.Base.ViewObject.hide()
00044     p = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Arch")
00045     c = p.GetUnsigned("WallColor")
00046     r = float((c>>24)&0xFF)/255.0
00047     g = float((c>>16)&0xFF)/255.0
00048     b = float((c>>8)&0xFF)/255.0
00049     obj.ViewObject.ShapeColor = (r,g,b,1.0)
00050     return obj
00051 
00052 class CommandWall:
00053     "the Arch Wall command definition"
00054     def GetResources(self):
00055         return {'Pixmap'  : 'Arch_Wall',
00056                 'MenuText': QtCore.QT_TRANSLATE_NOOP("Arch_Wall","Wall"),
00057                 'Accel': "W, A",
00058                 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Arch_Wall","Creates a wall object from scratch or from a selected object (wire, face or solid)")}
00059         
00060     def Activated(self):
00061         sel = FreeCADGui.Selection.getSelection()
00062         if sel:
00063             FreeCAD.ActiveDocument.openTransaction("Wall")
00064             for obj in sel:
00065                 makeWall(obj)
00066             FreeCAD.ActiveDocument.commitTransaction()
00067         else:
00068             wall = makeWall()
00069        
00070 class Wall(Component.Component):
00071     "The Wall object"
00072     def __init__(self,obj):
00073         Component.Component.__init__(self,obj)
00074         obj.addProperty("App::PropertyLength","Width","Base",
00075                         "The width of this wall. Not used if this wall is based on a face")
00076         obj.addProperty("App::PropertyLength","Height","Base",
00077                         "The height of this wall. Keep 0 for automatic. Not used if this wall is based on a solid")
00078         obj.addProperty("App::PropertyLength","Length","Base",
00079                         "The length of this wall. Not used if this wall is based on a shape")
00080         obj.addProperty("App::PropertyEnumeration","Align","Base",
00081                         "The alignment of this wall on its base object, if applicable")
00082         obj.Align = ['Left','Right','Center']
00083         self.Type = "Wall"
00084         obj.Width = 0.1
00085         obj.Length = 1
00086         obj.Height = 0
00087         
00088     def execute(self,obj):
00089         self.createGeometry(obj)
00090         
00091     def onChanged(self,obj,prop):
00092         if prop in ["Base","Height","Width","Align","Additions","Subtractions"]:
00093             self.createGeometry(obj)
00094 
00095     def createGeometry(self,obj):
00096         
00097         def getbase(wire):
00098             "returns a full shape from a base wire"
00099             dvec = fcgeo.vec(wire.Edges[0]).cross(normal)
00100             dvec.normalize()
00101             if obj.Align == "Left":
00102                 dvec = dvec.multiply(obj.Width)
00103                 w2 = fcgeo.offsetWire(wire,dvec)
00104                 sh = fcgeo.bind(wire,w2)
00105             elif obj.Align == "Right":
00106                 dvec = dvec.multiply(obj.Width)
00107                 dvec = fcvec.neg(dvec)
00108                 w2 = fcgeo.offsetWire(wire,dvec)
00109                 sh = fcgeo.bind(wire,w2)
00110             elif obj.Align == "Center":
00111                 dvec = dvec.multiply(obj.Width/2)
00112                 w1 = fcgeo.offsetWire(wire,dvec)
00113                 dvec = fcvec.neg(dvec)
00114                 w2 = fcgeo.offsetWire(wire,dvec)
00115                 sh = fcgeo.bind(w1,w2)
00116             if height:
00117                 norm = Vector(normal).multiply(height)
00118                 sh = sh.extrude(norm)
00119             return sh
00120         
00121         pl = obj.Placement
00122 
00123         # getting default values
00124         height = normal = None
00125         if obj.Height:
00126             height = obj.Height
00127         else:
00128             for p in obj.InList:
00129                 if Draft.getType(p) == "Floor":
00130                     height = p.Height
00131         if not height: height = 1
00132         if obj.Normal == Vector(0,0,0):
00133             normal = Vector(0,0,1)
00134         else:
00135             normal = Vector(obj.Normal)
00136 
00137         # computing shape
00138         if obj.Base:
00139             if obj.Base.isDerivedFrom("Part::Feature"):
00140                 base = obj.Base.Shape.copy()
00141                 if base.Solids:
00142                     pass
00143                 elif base.Faces:
00144                     if height:
00145                         norm = normal.multiply(height)
00146                         base = base.extrude(norm)
00147                 elif base.Wires:
00148                     temp = None
00149                     for wire in obj.Base.Shape.Wires:
00150                         sh = getbase(wire)
00151                         if temp:
00152                             temp = temp.oldFuse(sh)
00153                         else:
00154                             temp = sh
00155                     base = temp
00156         else:
00157             if obj.Length == 0:
00158                 return
00159             v1 = Vector(0,0,0)
00160             v2 = Vector(obj.Length,0,0)
00161             w = Part.Wire(Part.Line(v1,v2).toShape())
00162             base = getbase(w)
00163             
00164         for app in obj.Additions:
00165             base = base.oldFuse(app.Shape)
00166             app.ViewObject.hide() #to be removed
00167         for hole in obj.Subtractions:
00168             cut = False
00169             if hasattr(hole,"Proxy"):
00170                 if hasattr(hole.Proxy,"Subvolume"):
00171                     if hole.Proxy.Subvolume:
00172                         print "cutting subvolume",hole.Proxy.Subvolume
00173                         base = base.cut(hole.Proxy.Subvolume)
00174                         cut = True
00175             if not cut:
00176                 if hasattr(obj,"Shape"):
00177                     base = base.cut(hole.Shape)
00178                     hole.ViewObject.hide() # to be removed
00179         obj.Shape = base
00180         if not fcgeo.isNull(pl):
00181             obj.Placement = pl
00182 
00183 class ViewProviderWall(Component.ViewProviderComponent):
00184     "A View Provider for the Wall object"
00185 
00186     def __init__(self,vobj):
00187         Component.ViewProviderComponent.__init__(self,vobj)
00188 
00189     def getIcon(self):          
00190         return """
00191                 /* XPM */
00192                 static char * Arch_Wall_xpm[] = {
00193                 "16 16 9 1",
00194                 "       c None",
00195                 ".      c #543016",
00196                 "+      c #6D2F08",
00197                 "@      c #954109",
00198                 "#      c #874C24",
00199                 "$      c #AE6331",
00200                 "%      c #C86423",
00201                 "&      c #FD7C26",
00202                 "*      c #F5924F",
00203                 "                ",
00204                 "                ",
00205                 "       #        ",
00206                 "      ***$#     ",
00207                 "    .*******.   ",
00208                 "   *##$****#+   ",
00209                 " #**%&&##$#@@   ",
00210                 ".$**%&&&&+@@+   ",
00211                 "@&@#$$%&&@@+..  ",
00212                 "@&&&%#.#$#+..#$.",
00213                 " %&&&&+%#.$**$@+",
00214                 "   @%&+&&&$##@@+",
00215                 "     @.&&&&&@@@ ",
00216                 "        @%&&@@  ",
00217                 "           @+   ",
00218                 "                "};
00219                 """
00220 
00221 FreeCADGui.addCommand('Arch_Wall',CommandWall())

Generated on Wed Nov 23 19:01:02 2011 for FreeCAD by  doxygen 1.6.1