Made recommended formatting changes.

This commit is contained in:
David Daish
2020-04-01 17:02:05 +13:00
committed by Yorik van Havre
parent 8f910713d4
commit f868ff36ea
2 changed files with 411 additions and 423 deletions

View File

@@ -134,24 +134,24 @@ def removeFromComponent(compobject,subobject):
class Component(ArchIFC.IfcProduct): class Component(ArchIFC.IfcProduct):
"""The Arch Component object. """The Arch Component object.
Acts as a base for all other Arch objects, such as Arch walls and Arch Acts as a base for all other Arch objects, such as Arch walls and Arch
structures. It's properties and behaviours are common to all Arch objects. structures. It's properties and behaviours are common to all Arch objects.
You can learn more about Arch Components, and the purpose of Arch Components You can learn more about Arch Components, and the purpose of Arch Components
here: https://wiki.freecadweb.org/Arch_Component here: https://wiki.freecadweb.org/Arch_Component
""" """
def __init__(self, obj): def __init__(self, obj):
"""Initialises the Component. """Initialises the Component.
Registers the Proxy as this class object. Sets the object to have the Registers the Proxy as this class object. Sets the object to have the
properties of an Arch component. properties of an Arch component.
Parameters Parameters
---------- ----------
obj: <App::FeaturePython> obj: <App::FeaturePython>
The object to turn into an Arch Component The object to turn into an Arch Component
""" """
obj.Proxy = self obj.Proxy = self
Component.setProperties(self, obj) Component.setProperties(self, obj)
@@ -160,8 +160,8 @@ obj: <App::FeaturePython>
def setProperties(self, obj): def setProperties(self, obj):
"""Gives the component it's component specific properties, such as material. """Gives the component it's component specific properties, such as material.
You can learn more about properties here: https://wiki.freecadweb.org/property You can learn more about properties here: https://wiki.freecadweb.org/property
""" """
ArchIFC.IfcProduct.setProperties(self, obj) ArchIFC.IfcProduct.setProperties(self, obj)
@@ -236,29 +236,29 @@ You can learn more about properties here: https://wiki.freecadweb.org/property
def onBeforeChange(self,obj,prop): def onBeforeChange(self,obj,prop):
"""Method called before the object has a property changed. """Method called before the object has a property changed.
Specifically, this method is called before the value changes. Specifically, this method is called before the value changes.
If "Placement" has changed, it records the old placement, so that .onChanged() If "Placement" has changed, it records the old placement, so that .onChanged()
can compare between the old and new placement, and move it's children can compare between the old and new placement, and move it's children
accordingly. accordingly.
""" """
if prop == "Placement": if prop == "Placement":
self.oldPlacement = FreeCAD.Placement(obj.Placement) self.oldPlacement = FreeCAD.Placement(obj.Placement)
def onChanged(self, obj, prop): def onChanged(self, obj, prop):
"""Method called when the object has a property changed. """Method called when the object has a property changed.
If "Placement" has changed, the component moves any children components that If "Placement" has changed, the component moves any children components that
have been set to move with their host, such that they stay in the same location have been set to move with their host, such that they stay in the same location
to this component. to this component.
Also calls ArchIFC.IfcProduct.onChanged(). Also calls ArchIFC.IfcProduct.onChanged().
Parameters Parameters
---------- ----------
prop: string prop: string
The name of the property that has changed. The name of the property that has changed.
""" """
ArchIFC.IfcProduct.onChanged(self, obj, prop) ArchIFC.IfcProduct.onChanged(self, obj, prop)
@@ -293,15 +293,15 @@ prop: string
def getMovableChildren(self,obj): def getMovableChildren(self,obj):
"""Finds the component's children set to move with their host. """Finds the component's children set to move with their host.
In this case, children refer to Additions, Subtractions, and objects linked to In this case, children refer to Additions, Subtractions, and objects linked to
this object that refer to it as a host in the "Host" or "Hosts" properties. this object that refer to it as a host in the "Host" or "Hosts" properties.
Objects are set to move with their host via the MoveWithHost property. Objects are set to move with their host via the MoveWithHost property.
Returns Returns
------- -------
list of <App::FeaturePython> list of <App::FeaturePython>
List of child objects set to move with their host. List of child objects set to move with their host.
""" """
ilist = obj.Additions + obj.Subtractions ilist = obj.Additions + obj.Subtractions
for o in obj.InList: for o in obj.InList:
@@ -323,14 +323,14 @@ list of <App::FeaturePython>
def getParentHeight(self,obj): def getParentHeight(self,obj):
"""Gets a height value from hosts. """Gets a height value from hosts.
Recursively crawls hosts until it finds a Floor or BuildingPart, then returns Recursively crawls hosts until it finds a Floor or BuildingPart, then returns
the value of it's Height property. the value of it's Height property.
Returns Returns
------- -------
<App::PropertyLength> <App::PropertyLength>
The Height value of the found Floor or BuildingPart. The Height value of the found Floor or BuildingPart.
""" """
for parent in obj.InList: for parent in obj.InList:
if Draft.getType(parent) in ["Floor","BuildingPart"]: if Draft.getType(parent) in ["Floor","BuildingPart"]:
@@ -348,17 +348,17 @@ Returns
def clone(self,obj): def clone(self,obj):
"""If the object is a clone, copies the shape. """If the object is a clone, copies the shape.
If the object is a clone according to the "CloneOf" property, it copies the object's If the object is a clone according to the "CloneOf" property, it copies the object's
shape and several properties relating to shape, such as "Length" and "Thickness". shape and several properties relating to shape, such as "Length" and "Thickness".
Will only perform the copy if this object and the object it's a clone of are of the same Will only perform the copy if this object and the object it's a clone of are of the same
type, or if the object has the type "Component" or "BuildingPart". type, or if the object has the type "Component" or "BuildingPart".
Returns Returns
------- -------
bool bool
True if the copy occurs, False if otherwise. True if the copy occurs, False if otherwise.
""" """
if hasattr(obj,"CloneOf"): if hasattr(obj,"CloneOf"):
if obj.CloneOf: if obj.CloneOf:
@@ -375,14 +375,14 @@ bool
def getSiblings(self,obj): def getSiblings(self,obj):
"""Finds objects that have the same Base object, and type. """Finds objects that have the same Base object, and type.
Looks to base object, and finds other objects that are based off this base Looks to base object, and finds other objects that are based off this base
object. If these objects are the same type, returns them. object. If these objects are the same type, returns them.
Returns Returns
------- -------
list of <App::FeaturePython> list of <App::FeaturePython>
List of objects that have the same Base and type as this component. List of objects that have the same Base and type as this component.
""" """
if not hasattr(obj,"Base"): if not hasattr(obj,"Base"):
return [] return []
@@ -401,27 +401,27 @@ list of <App::FeaturePython>
def getExtrusionData(self,obj): def getExtrusionData(self,obj):
"""Gets the object's extrusion data. """Gets the object's extrusion data.
This method recursively scrapes the Bases of the object, until it finds a Base This method recursively scrapes the Bases of the object, until it finds a Base
that is derived from a <Part::Extrusion>. From there, it copies the extrusion that is derived from a <Part::Extrusion>. From there, it copies the extrusion
to the (0,0,0) origin. to the (0,0,0) origin.
With this copy, it gets the <Part.Face> the shape was originally extruded from, the With this copy, it gets the <Part.Face> the shape was originally extruded from, the
<Base.Vector> of the extrusion, and the <Base.Placement> needed to move the copy back to it's <Base.Vector> of the extrusion, and the <Base.Placement> needed to move the copy back to it's
original location/orientation. It will return this data as a tuple. original location/orientation. It will return this data as a tuple.
If it encounters an object derived from a <Part::Multifuse>, it will return this data If it encouters an object derived from a <Part::Multifuse>, it will return this data
as a tuple containing lists. The lists will contain the same data as above, from each as a tuple containing lists. The lists will contain the same data as above, from each
of the objects within the multifuse. of the objects within the multifuse.
Returns Returns
------- -------
tuple tuple
Tuple containing: Tuple containing:
1) The <Part.Face> the object was extruded from. 1) The <Part.Face> the object was extruded from.
2) The <Base.Vector> of the extrusion. 2) The <Base.Vector> of the extrusion.
3) The <Base.Placement> of the extrusion. 3) The <Base.Placement> of the extrusion.
""" """
if hasattr(obj,"CloneOf"): if hasattr(obj,"CloneOf"):
if obj.CloneOf: if obj.CloneOf:
@@ -506,22 +506,22 @@ tuple
def rebase(self,shape,hint=None): def rebase(self,shape,hint=None):
"""Copies a shape to the (0,0,0) origin. """Copies a shape to the (0,0,0) origin.
Creates a copy of a shape, such that it's center of mass is in the (0,0,0) Creates a copy of a shape, such that it's center of mass is in the (0,0,0)
origin. origin.
TODO Determine the way the shape is rotated by this method. TODO Determine the way the shape is rotated by this method.
Returns the copy of the shape, and the <Base.Placement> needed to move the copy Returns the copy of the shape, and the <Base.Placement> needed to move the copy
back to it's original location/orientation. back to it's original location/orientation.
Parameters Parameters
---------- ----------
shape: <Part.Shape> shape: <Part.Shape>
The shape to copy. The shape to copy.
hint: <Base.Vector>, optional hint: <Base.Vector>, optional
If the angle between the normal vector of the shape, and the hint vector is If the angle between the normal vector of the shape, and the hint vector is
greater than 90 degrees, the normal will be reversed before being rotated. greater than 90 degrees, the normal will be reversed before being rotated.
""" """
import DraftGeomUtils,math import DraftGeomUtils,math
@@ -541,10 +541,7 @@ hint: <Base.Vector>, optional
if hint and hint.getAngle(n) > 1.58: if hint and hint.getAngle(n) > 1.58:
n = n.negative() n = n.negative()
r = FreeCAD.Rotation( r = FreeCAD.Rotation(FreeCAD.Vector(0, 0, 1), n)
FreeCAD.Vector(0,0,1),
n
)
if round(abs(r.Angle),8) == round(math.pi,8): if round(abs(r.Angle),8) == round(math.pi,8):
r = FreeCAD.Rotation() r = FreeCAD.Rotation()
@@ -552,11 +549,9 @@ hint: <Base.Vector>, optional
for s in shape: for s in shape:
s = s.copy() s = s.copy()
s.translate(v.negative()) s.translate(v.negative())
s.rotate( s.rotate(FreeCAD.Vector(0, 0, 0),
FreeCAD.Vector(0,0,0), r.Axis,
r.Axis, math.degrees(-r.Angle))
math.degrees(-r.Angle)
)
shapes.append(s) shapes.append(s)
p = FreeCAD.Placement() p = FreeCAD.Placement()
p.Base = v p.Base = v
@@ -569,19 +564,19 @@ hint: <Base.Vector>, optional
def hideSubobjects(self,obj,prop): def hideSubobjects(self,obj,prop):
"""Hides Additions and Subtractions of this Component when that list changes. """Hides Additions and Subtractions of this Component when that list changes.
Intended to be used in conjunction with the .onChanged() method, to access the Intended to be used in conjunction with the .onChanged() method, to access the
property that has changed. property that has changed.
When an object loses or gains an Addition, this method hides all Additions. When an object loses or gains an Addition, this method hides all Additions.
When it gains or loses a Subtraction, this method hides all Subtractions. When it gains or loses a Subtraction, this method hides all Subtractions.
Does not effect objects of type Window, or clones of Windows. Does not effect objects of type Window, or clones of Windows.
Parameters Parameters
---------- ----------
prop: string prop: string
The name of the property that has changed. The name of the property that has changed.
""" """
if FreeCAD.GuiUp: if FreeCAD.GuiUp:
if prop in ["Additions","Subtractions"]: if prop in ["Additions","Subtractions"]:
@@ -602,28 +597,28 @@ prop: string
def processSubShapes(self,obj,base,placement=None): def processSubShapes(self,obj,base,placement=None):
"""Adds Additions and Subtractions to a base shape. """Adds Additions and Subtractions to a base shape.
If Additions exist, fuses then to the base shape. If no base is provided, it If Additions exist, fuses then to the base shape. If no base is provided, it
will just fuse other additions to the first addition. will just fuse other additions to the first addition.
If Subtractions exist, it will cut them from the base shape. Roofs and Windows If Subtractions exist, it will cut them from the base shape. Roofs and Windows
are treated uniquely, as they define their own Shape to subtract from parent are treated uniquely, as they define their own Shape to subtract from parent
shapes using their .getSubVolume() methods. shapes using their .getSubVolume() methods.
TODO determine what the purpose of the placement argument is. TODO determine what the purpose of the placement argument is.
Parameters Parameters
---------- ----------
base: <Part.Shape>, optional base: <Part.Shape>, optional
The base shape to add Additions and Subtractions to. The base shape to add Additions and Subtractions to.
placement: <Base.Placement>, optional placement: <Base.Placement>, optional
Prior to adding or subtracting subshapes, the <Base.Placement> of the Prior to adding or subtracting subshapes, the <Base.Placement> of the
subshapes are multiplied by the inverse of this parameter. subshapes are multiplied by the inverse of this parameter.
Returns Returns
------- -------
<Part.Shape> <Part.Shape>
The base shape, with the additions and subtractions performed. The base shape, with the additions and subtractions performed.
""" """
import Draft,Part import Draft,Part
#print("Processing subshapes of ",obj.Label, " : ",obj.Additions) #print("Processing subshapes of ",obj.Label, " : ",obj.Additions)
@@ -726,26 +721,25 @@ Returns
def spread(self,obj,shape,placement=None): def spread(self,obj,shape,placement=None):
"""Copies the object to it's Axis's points. """Copies the object to it's Axis's points.
If the object has the "Axis" property assigned, this method creates a copy of If the object has the "Axis" property assigned, this method creates a copy of
the shape for each point on the object assigned as the "Axis". Each of these the shape for each point on the object assigned as the "Axis". Each of these
copies are then translated, equal to the displacement of the points from the copies are then translated, equal to the displacement of the points from the
(0,0,0) origin. (0,0,0) origin.
If the object's "Axis" is unassigned, returns the original shape unchanged. If the object's "Axis" is unassigned, returns the original shape unchanged.
Parameters Parameters
---------- ----------
shape: <Part.Shape> shape: <Part.Shape>
The shape to copy. The shape to copy.
placement: placement:
Does nothing. Does nothing.
Returns Returns
------- -------
<Part.Shape> <Part.Shape>
The shape, either spread to the axis points, or unchanged. The shape, either spread to the axis points, or unchanged.
"""
"""
points = None points = None
if hasattr(obj,"Axis"): if hasattr(obj,"Axis"):
@@ -769,19 +763,19 @@ Returns
def isIdentity(self,placement): def isIdentity(self,placement):
"""Checks if a placement is *almost* zero. """Checks if a placement is *almost* zero.
Check if a <Base.Placement>'s displacement from (0,0,0) is almost zero, and if Check if a <Base.Placement>'s displacement from (0,0,0) is almost zero, and if
the angle of it's rotation about it's axis is almost zero. the angle of it's rotation about it's axis is almost zero.
Parameters Parameters
---------- ----------
placement: <Base.Placement> placement: <Base.Placement>
The placement to examine. The placement to examine.
Returns Returns
------- -------
bool bool
Returns true if angle and displacement are almost zero, false it otherwise. Returns true if angle and displacement are almost zero, false it otherwise.
""" """
if (placement.Base.Length < 0.000001) and (placement.Rotation.Angle < 0.000001): if (placement.Base.Length < 0.000001) and (placement.Rotation.Angle < 0.000001):
return True return True
@@ -790,26 +784,26 @@ bool
def applyShape(self,obj,shape,placement,allowinvalid=False,allownosolid=False): def applyShape(self,obj,shape,placement,allowinvalid=False,allownosolid=False):
"""Checks the given shape, then assigns it to the object. """Checks the given shape, then assigns it to the object.
Checks if the shape is valid, isn't null, and if it has volume. Removes Checks if the shape is valid, isn't null, and if it has volume. Removes
redundant edges from the shape. Spreads shape to the "Axis" with method redundant edges from the shape. Spreads shape to the "Axis" with method
.spread(). .spread().
Sets the object's Shape and Placement to the values given, if successful. Sets the object's Shape and Placement to the values given, if successful.
Finally, runs .computeAreas() method, to calculate the horizontal and vertical Finally, runs .computeAreas() method, to calculate the horizontal and vertical
area of the shape. area of the shape.
Parameters Parameters
---------- ----------
shape: <Part.Shape> shape: <Part.Shape>
The shape to check and apply to the object. The shape to check and apply to the object.
placement: <Base.Placement> placement: <Base.Placement>
The placement to apply to the object. The placement to apply to the object.
allowinvalid: bool, optional allowinvalid: bool, optional
Whether to allow invalid shapes, or to throw an error. Whether to allow invalid shapes, or to throw an error.
allownosolid: bool, optional allownosolid: bool, optional
Whether to allow non-solid shapes, or to throw an error. Whether to allow non-solid shapes, or to throw an error.
""" """
if shape: if shape:
if not shape.isNull(): if not shape.isNull():
@@ -854,19 +848,19 @@ allownosolid: bool, optional
def computeAreas(self,obj): def computeAreas(self,obj):
"""Computes the area properties of the object's shape. """Computes the area properties of the object's shape.
Computes the vertical area, horizontal area, and perimeter length of the Computes the vertical area, horizontal area, and perimeter length of the
object's shape. object's shape.
The vertical area is the surface area of the faces perpendicular to the ground. The vertical area is the surface area of the faces perpendicular to the ground.
The horizontal area is the area of the shape, when projected onto a hyperplane The horizontal area is the area of the shape, when projected onto a hyperplane
across the XY axises, IE: the area when viewed from a bird's eye view. across the XY axises, IE: the area when viewed from a bird's eye view.
The perimeter length is the length of the outside edges of this bird's eye view. The perimeter length is the length of the outside edges of this bird's eye view.
These values are assigned to the object's "VerticalArea", "HorizontalArea", and These values are assigned to the object's "VerticalArea", "HorizontalArea", and
"PerimeterLength" properties. "PerimeterLength" properties.
""" """
if (not obj.Shape) or obj.Shape.isNull() or (not obj.Shape.isValid()) or (not obj.Shape.Faces): if (not obj.Shape) or obj.Shape.isNull() or (not obj.Shape.isValid()) or (not obj.Shape.Faces):
@@ -937,22 +931,22 @@ These values are assigned to the object's "VerticalArea", "HorizontalArea", and
def isStandardCase(self,obj): def isStandardCase(self,obj):
"""Determines if the component is a standard case of it's IFC type. """Determines if the component is a standard case of it's IFC type.
Not all IFC types have a standard case. Not all IFC types have a standard case.
If an object is a standard case or not varies between the different types. Each If an object is a standard case or not varies between the different types. Each
type has it's own rules to define what is a standard case. type has it's own rules to define what is a standard case.
Rotated objects, or objects with Additions or Subtractions are not standard Rotated objects, or objects with Additions or Subtractions are not standard
cases. cases.
All objects whose IfcType is suffixed with the string " Sandard Case" is All objects whose IfcType is suffixed with the string " Sandard Case" is
automatically a standard case. automatically a standard case.
Returns Returns
------- -------
bool bool
Whether the object is a standard case or not. Whether the object is a standard case or not.
""" """
# Standard Case has been set manually by the user # Standard Case has been set manually by the user
if obj.IfcType.endswith("Standard Case"): if obj.IfcType.endswith("Standard Case"):
@@ -1006,22 +1000,22 @@ bool
class ViewProviderComponent: class ViewProviderComponent:
"""A default View Provider for Component objects. """A default View Provider for Component objects.
Acts as a base for all other Arch view providers. Its properties and Acts as a base for all other Arch view providers. Its properties and
behaviours are common to all Arch view providers. behaviours are common to all Arch view providers.
""" """
def __init__(self,vobj): def __init__(self,vobj):
"""Initialises the Component view provider. """Initialises the Component view provider.
Registers the Proxy as this class object. Registers the Object, as the view Registers the Proxy as this class object. Registers the Object, as the view
provider's object. Sets the view provider to have the provider's object. Sets the view provider to have the
properties of an Arch component. properties of an Arch component.
Parameters Parameters
---------- ----------
vobj: <Gui.ViewProviderDocumentObject> vobj: <Gui.ViewProviderDocumentObject>
The view provider to turn into an Component view provider. The view provider to turn into an Component view provider.
""" """
vobj.Proxy = self vobj.Proxy = self
self.Object = vobj.Object self.Object = vobj.Object
@@ -1030,8 +1024,8 @@ vobj: <Gui.ViewProviderDocumentObject>
def setProperties(self,vobj): def setProperties(self,vobj):
"""Gives the component view provider it's component view provider specific properties. """Gives the component view provider it's component view provider specific properties.
You can learn more about properties here: https://wiki.freecadweb.org/property You can learn more about properties here: https://wiki.freecadweb.org/property
""" """
if not "UseMaterialColor" in vobj.PropertiesList: if not "UseMaterialColor" in vobj.PropertiesList:
vobj.addProperty("App::PropertyBool","UseMaterialColor","Component",QT_TRANSLATE_NOOP("App::Property","Use the material color as this object's shape color, if available")) vobj.addProperty("App::PropertyBool","UseMaterialColor","Component",QT_TRANSLATE_NOOP("App::Property","Use the material color as this object's shape color, if available"))
@@ -1040,17 +1034,17 @@ You can learn more about properties here: https://wiki.freecadweb.org/property
def updateData(self,obj,prop): def updateData(self,obj,prop):
"""Method called when the host object has a property changed. """Method called when the host object has a property changed.
If the object has a Material associated with it, matches the view object's If the object has a Material associated with it, matches the view object's
ShapeColor and Transparency to match the Material. ShapeColor and Transparency to match the Material.
If the object is now cloned, or is part of a compound, the view object inherits If the object is now cloned, or is part of a compound, the view object inherits
the DiffuseColor. the DiffuseColor.
Parameters Parameters
---------- ----------
prop: string prop: string
The name of the property that has changed. The name of the property that has changed.
""" """
#print(obj.Name," : updating ",prop) #print(obj.Name," : updating ",prop)
if prop == "Material": if prop == "Material":
@@ -1092,14 +1086,14 @@ prop: string
def getIcon(self): def getIcon(self):
"""Returns the path to the appropriate icon. """Returns the path to the appropriate icon.
If a clone, returns the cloned component icon path. Otherwise returns the Arch Component If a clone, returns the cloned component icon path. Otherwise returns the Arch Component
icon. icon.
Returns Returns
------- -------
str str
Path to the appropriate icon .svg file. Path to the appropriate icon .svg file.
""" """
import Arch_rc import Arch_rc
if hasattr(self,"Object"): if hasattr(self,"Object"):
@@ -1111,19 +1105,19 @@ str
def onChanged(self,vobj,prop): def onChanged(self,vobj,prop):
"""Method called when the view provider has a property changed. """Method called when the view provider has a property changed.
If DiffuseColor changes, change DiffuseColor to copy the host object's clone, If DiffuseColor changes, change DiffuseColor to copy the host object's clone,
if it exists. if it exists.
If ShapeColor changes, overwrite it with DiffuseColor. If ShapeColor changes, overwrite it with DiffuseColor.
If Visibility changes, propagate the change to all view objects that are also If Visibility changes, propagate the change to all view objects that are also
hosted by this view object's host. hosted by this view object's host.
Parameters Parameters
---------- ----------
prop: string prop: string
The name of the property that has changed. The name of the property that has changed.
""" """
#print(vobj.Object.Name, " : changing ",prop) #print(vobj.Object.Name, " : changing ",prop)
#if prop == "Visibility": #if prop == "Visibility":

View File

@@ -48,56 +48,56 @@ __author__ = "Yorik van Havre"
__url__ = "http://www.freecadweb.org" __url__ = "http://www.freecadweb.org"
__doc__="""This module provides tools to build Wall objects. Walls are simple __doc__="""This module provides tools to build Wall objects. Walls are simple
objects, usually vertical, typically obtained by giving a thickness to a base objects, usually vertical, typically obtained by giving a thickness to a base
line, then extruding it vertically. line, then extruding it vertically.
Examples Examples
-------- --------
TODO put examples here. TODO put examples here.
""" """
def makeWall(baseobj=None,height=None,length=None,width=None,align="Center",face=None,name="Wall"): def makeWall(baseobj=None,height=None,length=None,width=None,align="Center",face=None,name="Wall"):
'''Creates a wall based on a given object, and returns the generated wall. """Creates a wall based on a given object, and returns the generated wall.
TODO: It is unclear what defines which units this function uses. TODO: It is unclear what defines which units this function uses.
Parameters Parameters
---------- ----------
baseobj: <Part::PartFeature>, optional baseobj: <Part::PartFeature>, optional
The base object with which to build the wall. This can be a sketch, a draft The base object with which to build the wall. This can be a sketch, a draft
object, a face, or a solid. It can also be left as None. object, a face, or a solid. It can also be left as None.
height: float, optional height: float, optional
The height of the wall. The height of the wall.
length: float, optional length: float, optional
The length of the wall. Not used if the wall is based off an object. The length of the wall. Not used if the wall is based off an object.
Will use Arch default if left empty. Will use Arch default if left empty.
width: float, optional width: float, optional
The width of the wall. Not used if the base object is a face. Will The width of the wall. Not used if the base object is a face. Will
use Arch default if left empty. use Arch default if left empty.
align: str, optional align: str, optional
Either "Center", "Left", or "Right". Effects the alignment of the wall on Either "Center", "Left", or "Right". Effects the alignment of the wall on
it's baseline. it's baseline.
face: int, optional face: int, optional
The index number of a face on the given baseobj, to base the wall on. The index number of a face on the given baseobj, to base the wall on.
name: str, optional name: str, optional
The name to give to the created wall. The name to give to the created wall.
Returns Returns
------- -------
<Part::FeaturePython> <Part::FeaturePython>
Returns the generated wall. Returns the generated wall.
Notes Notes
----- -----
Creates a new <Part::FeaturePython> object, and turns it into a parametric wall Creates a new <Part::FeaturePython> object, and turns it into a parametric wall
object. This <Part::FeaturePython> object does not yet have any shape. object. This <Part::FeaturePython> object does not yet have any shape.
The wall then uses the baseobj.Shape as the basis to extrude out a wall shape, The wall then uses the baseobj.Shape as the basis to extrude out a wall shape,
giving the new <Part::FeaturePython> object a shape. giving the new <Part::FeaturePython> object a shape.
It then hides the original baseobj. It then hides the original baseobj.
''' """
if not FreeCAD.ActiveDocument: if not FreeCAD.ActiveDocument:
FreeCAD.Console.PrintError("No active document. Aborting\n") FreeCAD.Console.PrintError("No active document. Aborting\n")
@@ -134,24 +134,24 @@ It then hides the original baseobj.
def joinWalls(walls,delete=False): def joinWalls(walls,delete=False):
""" Joins the given list of walls into one sketch-based wall. """ Joins the given list of walls into one sketch-based wall.
Takes the first wall in the list, and adds on the other walls in the list. Takes the first wall in the list, and adds on the other walls in the list.
Returns the modified first wall. Returns the modified first wall.
Setting delete to True, will delete the other walls. Will only join walls if Setting delete to True, will delete the other walls. Will only join walls if
the walls have the same width, height and alignment. the walls have the same width, height and alignment.
Parameters Parameters
---------- ----------
walls: list of <Part::FeaturePython> walls: list of <Part::FeaturePython>
List containing the walls to add to the first wall in the list. Walls must List containing the walls to add to the first wall in the list. Walls must
be based off a base object. be based off a base object.
delete: bool, optional delete: bool, optional
If True, deletes the other walls in the list. If True, deletes the other walls in the list.
Returns Returns
------- -------
<Part::FeaturePython> <Part::FeaturePython>
""" """
import Part import Part
if not walls: if not walls:
@@ -190,9 +190,9 @@ Returns
def mergeShapes(w1,w2): def mergeShapes(w1,w2):
"""Not currently implemented. """Not currently implemented.
Returns a Shape built on two walls that share same properties and have a Returns a Shape built on two walls that share same properties and have a
coincident endpoint. coincident endpoint.
""" """
if not areSameWallTypes([w1,w2]): if not areSameWallTypes([w1,w2]):
return None return None
@@ -219,15 +219,15 @@ coincident endpoint.
def areSameWallTypes(walls): def areSameWallTypes(walls):
"""Checks if a list of walls have the same height, width and alignment. """Checks if a list of walls have the same height, width and alignment.
Parameters Parameters
---------- ----------
walls: list of <class 'ArchComponent.Component'> walls: list of <class 'ArchComponent.Component'>
Returns Returns
------- -------
bool bool
True if the walls have the same height, width and alignment, false if otherwise. True if the walls have the same height, width and alignment, false if otherwise.
""" """
for att in ["Width","Height","Align"]: for att in ["Width","Height","Align"]:
value = None value = None
@@ -250,13 +250,13 @@ bool
class _CommandWall: class _CommandWall:
"""The command definition for the Arch workbench's gui tool, Arch Wall. A tool for creating Arch walls. """The command definition for the Arch workbench's gui tool, Arch Wall. A tool for creating Arch walls.
Creates a wall from the object selected by the user. If no objects are Creates a wall from the object selected by the user. If no objects are
selected, enters an interactive mode to create a wall using selected points selected, enters an interactive mode to create a wall using selected points
to create a base. to create a base.
Find documentation on the end user usage of Arch Wall here: Find documentation on the end user usage of Arch Wall here:
https://wiki.freecadweb.org/Arch_Wall https://wiki.freecadweb.org/Arch_Wall
""" """
def GetResources(self): def GetResources(self):
"""Returns a dictionary with the visual aspects of the Arch Wall tool.""" """Returns a dictionary with the visual aspects of the Arch Wall tool."""
@@ -277,10 +277,10 @@ https://wiki.freecadweb.org/Arch_Wall
def Activated(self): def Activated(self):
"""Executed when Arch Wall is called. """Executed when Arch Wall is called.
Creates a wall from the object selected by the user. If no objects are Creates a wall from the object selected by the user. If no objects are
selected, enters an interactive mode to create a wall using selected points selected, enters an interactive mode to create a wall using selected points
to create a base. to create a base.
""" """
p = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Arch") p = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Arch")
self.Align = ["Center","Left","Right"][p.GetInt("WallAlignment",0)] self.Align = ["Center","Left","Right"][p.GetInt("WallAlignment",0)]
@@ -327,25 +327,23 @@ to create a base.
self.tracker = DraftTrackers.boxTracker() self.tracker = DraftTrackers.boxTracker()
if hasattr(FreeCAD,"DraftWorkingPlane"): if hasattr(FreeCAD,"DraftWorkingPlane"):
FreeCAD.DraftWorkingPlane.setup() FreeCAD.DraftWorkingPlane.setup()
FreeCADGui.Snapper.getPoint( FreeCADGui.Snapper.getPoint(callback=self.getPoint,
callback=self.getPoint, extradlg=self.taskbox(),
extradlg=self.taskbox(), title=translate("Arch","First point of wall")+":")
title=translate("Arch","First point of wall")+":"
)
def getPoint(self,point=None,obj=None): def getPoint(self,point=None,obj=None):
"""Callback for clicks during interactive mode. """Callback for clicks during interactive mode.
When method _CommandWall.Activated() has entered the interactive mode, this When method _CommandWall.Activated() has entered the interactive mode, this
callback runs when the user clicks. callback runs when the user clicks.
Parameters Parameters
---------- ----------
point: <class 'Base.Vector'> point: <class 'Base.Vector'>
The point the user has selected. The point the user has selected.
obj: <Part::PartFeature>, optional obj: <Part::PartFeature>, optional
The object the user's cursor snapped to, if any. The object the user's cursor snapped to, if any.
""" """
if obj: if obj:
if Draft.getType(obj) == "Wall": if Draft.getType(obj) == "Wall":
@@ -359,20 +357,16 @@ obj: <Part::PartFeature>, optional
self.tracker.width(self.Width) self.tracker.width(self.Width)
self.tracker.height(self.Height) self.tracker.height(self.Height)
self.tracker.on() self.tracker.on()
FreeCADGui.Snapper.getPoint( FreeCADGui.Snapper.getPoint(last=self.points[0],
last=self.points[0], callback=self.getPoint,
callback=self.getPoint, movecallback=self.update,
movecallback=self.update, extradlg=self.taskbox(),
extradlg=self.taskbox(), title=translate("Arch","Next point")+":",mode="line")
title=translate("Arch","Next point")+":",mode="line"
)
elif len(self.points) == 2: elif len(self.points) == 2:
import Part import Part
l = Part.LineSegment( l = Part.LineSegment(FreeCAD.DraftWorkingPlane.getLocalCoords(self.points[0]),
FreeCAD.DraftWorkingPlane.getLocalCoords(self.points[0]), FreeCAD.DraftWorkingPlane.getLocalCoords(self.points[1])
FreeCAD.DraftWorkingPlane.getLocalCoords(self.points[1])
)
self.tracker.finalize() self.tracker.finalize()
FreeCAD.ActiveDocument.openTransaction(translate("Arch","Create Wall")) FreeCAD.ActiveDocument.openTransaction(translate("Arch","Create Wall"))
FreeCADGui.addModule("Arch") FreeCADGui.addModule("Arch")
@@ -408,12 +402,12 @@ obj: <Part::PartFeature>, optional
def addDefault(self): def addDefault(self):
"""Creates a wall using a line segment, with all parameters as the default. """Creates a wall using a line segment, with all parameters as the default.
Used solely by _CommandWall.getPoint() when the interactive mode has selected Used solely by _CommandWall.getPoint() when the interactive mode has selected
two points. two points.
Relies on the assumption that FreeCADGui.doCommand() has already created a Relies on the assumption that FreeCADGui.doCommand() has already created a
Part.LineSegment assigned as the variable "trace" Part.LineSegment assigned as the variable "trace"
""" """
FreeCADGui.addModule("Draft") FreeCADGui.addModule("Draft")
if FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Arch").GetBool("WallSketches",True): if FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Arch").GetBool("WallSketches",True):
@@ -432,15 +426,15 @@ Part.LineSegment assigned as the variable "trace"
def update(self,point): def update(self,point):
"""Callback for the mouse moving during the interactive mode. """Callback for the mouse moving during the interactive mode.
Updates the active dialog box to show the coordinates of the location of the Updates the active dialog box to show the co-ordinates of the location of the
cursor. It also shows the length the line would take, if the user selected that cursor. It also shows the length the line would take, if the user selected that
point. point.
Parameters Parameters
---------- ----------
point: <class 'Base.Vector'> point: <class 'Base.Vector'>
The point the cursor is currently at, or has snapped to. The point the cursor is currently at, or has snapped to.
""" """
if FreeCADGui.Control.activeDialog(): if FreeCADGui.Control.activeDialog():
b = self.points[0] b = self.points[0]
@@ -581,8 +575,8 @@ point: <class 'Base.Vector'>
def setContinue(self,i): def setContinue(self,i):
"""Simple callback to set if the interactive mode will restart when finished. """Simple callback to set if the interactive mode will restart when finished.
This allows for several walls to be placed one after another. This allows for several walls to be placed one after another.
""" """
self.continueCmd = bool(i) self.continueCmd = bool(i)
if hasattr(FreeCADGui,"draftToolBar"): if hasattr(FreeCADGui,"draftToolBar"):
@@ -610,11 +604,11 @@ This allows for several walls to be placed one after another.
class _CommandMergeWalls: class _CommandMergeWalls:
"""The command definition for the Arch workbench's gui tool, Arch MergeWalls. A tool for merging walls. """The command definition for the Arch workbench's gui tool, Arch MergeWalls. A tool for merging walls.
Joins two or more walls by using the ArchWall.joinWalls() function. Joins two or more walls by using the ArchWall.joinWalls() function.
Find documentation on the end user usage of Arch Wall here: Find documentation on the end user usage of Arch Wall here:
https://wiki.freecadweb.org/Arch_MergeWalls https://wiki.freecadweb.org/Arch_MergeWalls
""" """
def GetResources(self): def GetResources(self):
"""Returns a dictionary with the visual aspects of the Arch MergeWalls tool.""" """Returns a dictionary with the visual aspects of the Arch MergeWalls tool."""
@@ -634,11 +628,12 @@ https://wiki.freecadweb.org/Arch_MergeWalls
def Activated(self): def Activated(self):
"""Executed when Arch MergeWalls is called. """Executed when Arch MergeWalls is called.
Calls ArchWall.joinWalls() on walls selected by the user, with the delete Calls ArchWall.joinWalls() on walls selected by the user, with the delete
option enabled. If the user has selected a single wall, check to see if the option enabled. If the user has selected a single wall, check to see if the
wall has any Additions that are walls. If so, merges these additions to the wall has any Additions that are walls. If so, merges these additions to the
wall, deleting the additions. wall, deleting the additions.
""" """
walls = FreeCADGui.Selection.getSelection() walls = FreeCADGui.Selection.getSelection()
if len(walls) == 1: if len(walls) == 1:
if Draft.getType(walls[0]) == "Wall": if Draft.getType(walls[0]) == "Wall":
@@ -672,21 +667,21 @@ wall, deleting the additions.
class _Wall(ArchComponent.Component): class _Wall(ArchComponent.Component):
"""The Wall object. Takes a <App::FeaturePython> and turns it into a wall. """The Wall object. Takes a <App::FeaturePython> and turns it into a wall.
Walls are simple objects, usually vertical, typically obtained by giving a Walls are simple objects, usually vertical, typically obtained by giving a
thickness to a base line, then extruding it vertically. thickness to a base line, then extruding it vertically.
Parameters Parameters
---------- ----------
obj: <App::FeaturePython> obj: <App::FeaturePython>
The object to turn into a wall. Note that this is not the object that forms The object to turn into a wall. Note that this is not the object that forms
the basis for the new wall's shape. That is given later. the basis for the new wall's shape. That is given later.
""" """
def __init__(self, obj): def __init__(self, obj):
"""Initialises the object's properties. """Initialises the object's properties.
Sets the object to have the properties of an Arch component, and Arch wall. Sets the object to have the properties of an Arch component, and Arch wall.
""" """
ArchComponent.Component.__init__(self, obj) ArchComponent.Component.__init__(self, obj)
self.setProperties(obj) self.setProperties(obj)
@@ -695,13 +690,13 @@ Sets the object to have the properties of an Arch component, and Arch wall.
def setProperties(self, obj): def setProperties(self, obj):
"""Gives the wall it's wall specific properties, such as it's alignment. """Gives the wall it's wall specific properties, such as it's alignment.
You can learn more about properties here: https://wiki.freecadweb.org/property You can learn more about properties here: https://wiki.freecadweb.org/property
parameters parameters
---------- ----------
obj: <part::featurepython> obj: <part::featurepython>
The object to turn into a wall. The object to turn into a wall.
""" """
lp = obj.PropertiesList lp = obj.PropertiesList
if not "Length" in lp: if not "Length" in lp:
@@ -1257,29 +1252,25 @@ obj: <part::featurepython>
# Get the 'offseted' wire taking into account # Get the 'offseted' wire taking into account
# of Width and Align of each edge, and overall # of Width and Align of each edge, and overall
# Offset # Offset
w2 = DraftGeomUtils.offsetWire( w2 = DraftGeomUtils.offsetWire(wire, dvec,
wire,dvec, bind=False,
bind=False, occ=False,
occ=False, widthList=widths,
widthList=widths, offsetMode=None,
offsetMode=None, alignList=aligns,
alignList=aligns, normal=normal,
normal=normal, basewireOffset=off)
basewireOffset=off
)
# Get the 'base' wire taking into account of # Get the 'base' wire taking into account of
# width and align of each edge # width and align of each edge
w1 = DraftGeomUtils.offsetWire( w1 = DraftGeomUtils.offsetWire(wire, dvec,
wire, dvec, bind=False,
bind=False, occ=False,
occ=False, widthList=widths,
widthList=widths, offsetMode="BasewireMode",
offsetMode="BasewireMode", alignList=aligns,
alignList=aligns, normal=normal,
normal=normal, basewireOffset=off)
basewireOffset=off
)
sh = DraftGeomUtils.bind(w1,w2) sh = DraftGeomUtils.bind(w1,w2)
elif curAligns == "Right": elif curAligns == "Right":
@@ -1298,20 +1289,23 @@ obj: <part::featurepython>
# dvec2 = DraftVecUtils.scaleTo(dvec,off) # dvec2 = DraftVecUtils.scaleTo(dvec,off)
# wire = DraftGeomUtils.offsetWire(wire,dvec2) # wire = DraftGeomUtils.offsetWire(wire,dvec2)
w2 = DraftGeomUtils.offsetWire( w2 = DraftGeomUtils.offsetWire(wire, dvec,
wire, dvec, bind=False,
bind=False, occ=False,
occ=False, widthList=widths,
widthList=widths, offsetMode=None,
offsetMode=None, alignList=aligns,
alignList=aligns, normal=normal,
normal=normal, basewireOffset=off)
basewireOffset=off
)
w1 = DraftGeomUtils.offsetWire( w1 = DraftGeomUtils.offsetWire(wire, dvec,
basewireOffset=off bind=False,
) occ=False,
widthList=widths,
offsetMode="BasewireMode",
alignList=aligns,
normal=normal,
basewireOffset=off)
sh = DraftGeomUtils.bind(w1,w2) sh = DraftGeomUtils.bind(w1,w2)
@@ -1328,24 +1322,24 @@ obj: <part::featurepython>
w2 = DraftGeomUtils.offsetWire(wire,d1) w2 = DraftGeomUtils.offsetWire(wire,d1)
else: else:
dvec.multiply(width) dvec.multiply(width)
w2 = DraftGeomUtils.offsetWire(
wire, dvec, w2 = DraftGeomUtils.offsetWire(wire, dvec,
bind=False, bind=False,
occ=False, occ=False,
widthList=widths, widthList=widths,
offsetMode=None, offsetMode=None,
alignList=aligns, alignList=aligns,
normal=normal normal=normal)
)
w1 = DraftGeomUtils.offsetWire( w1 = DraftGeomUtils.offsetWire(wire, dvec,
wire, dvec, bind=False,
bind=False, occ=False,
occ=False, widthList=widths,
widthList=widths, offsetMode="BasewireMode",
offsetMode="BasewireMode", alignList=aligns,
alignList=aligns, normal=normal)
normal=normal
)
sh = DraftGeomUtils.bind(w1,w2) sh = DraftGeomUtils.bind(w1,w2)
del widths[0:edgeNum] del widths[0:edgeNum]