Arch: misc improvements and bugfixes

* Allow mesh-based windows (with non-solid shape) to pass through
* Allow precast elements to be clones
* Structure elements now display a different icon when thry are clones
* Arch clones now get the same placements as their cloned object on create
* Fixed the bad export of clones to IFC
* Recoded the Site/Building/Floor IFC export to be more flexible
This commit is contained in:
Yorik van Havre
2016-06-15 21:17:44 -03:00
parent 9e4a10fee8
commit 741ea3f3cd
8 changed files with 402 additions and 28 deletions

View File

@@ -645,7 +645,7 @@ class Component:
print "Arch: unable to cut object ",o.Name, " from ", obj.Name
return base
def applyShape(self,obj,shape,placement):
def applyShape(self,obj,shape,placement,allowinvalid=False,allownosolid=False):
"checks and cleans the given shape, and apply it to the object"
if shape:
if not shape.isNull():
@@ -662,8 +662,16 @@ class Component:
obj.Placement = placement
else:
FreeCAD.Console.PrintWarning(obj.Label + " " + translate("Arch","has no solid")+"\n")
if allownosolid:
obj.Shape = shape
if not placement.isNull():
obj.Placement = placement
else:
FreeCAD.Console.PrintWarning(obj.Label + " " + translate("Arch","has an invalid shape")+"\n")
if allowinvalid:
obj.Shape = shape
if not placement.isNull():
obj.Placement = placement
else:
FreeCAD.Console.PrintWarning(obj.Label + " " + translate("Arch","has a null shape")+"\n")

View File

@@ -52,6 +52,11 @@ class _Precast(ArchComponent.Component):
def getExtrusionVector(self,obj,noplacement=True):
return FreeCAD.Vector()
def execute(self,obj):
if self.clone(obj):
return
class _PrecastBeam(_Precast):
@@ -68,6 +73,9 @@ class _PrecastBeam(_Precast):
obj.Role = ["Beam"]
def execute(self,obj):
if self.clone(obj):
return
pl = obj.Placement
length = obj.Length.Value
@@ -168,6 +176,9 @@ class _PrecastIbeam(_Precast):
obj.Role = ["Beam"]
def execute(self,obj):
if self.clone(obj):
return
pl = obj.Placement
length = obj.Length.Value
@@ -220,6 +231,9 @@ class _PrecastPillar(_Precast):
obj.Role = ["Column"]
def execute(self,obj):
if self.clone(obj):
return
pl = obj.Placement
length = obj.Length.Value
@@ -336,6 +350,9 @@ class _PrecastPanel(_Precast):
obj.Role = ["Plate"]
def execute(self,obj):
if self.clone(obj):
return
pl = obj.Placement
length = obj.Length.Value
@@ -432,6 +449,9 @@ class _PrecastSlab(_Precast):
obj.SlabType = ["Champagne","Hat"]
def execute(self,obj):
if self.clone(obj):
return
pl = obj.Placement
slabtype = obj.SlabType
@@ -514,6 +534,9 @@ class _ViewProviderPrecast(ArchComponent.ViewProviderComponent):
def getIcon(self):
import Arch_rc
if hasattr(self,"Object"):
if self.Object.CloneOf:
return ":/icons/Arch_Structure_Clone.svg"
return ":/icons/Arch_Structure_Tree.svg"
def setEdit(self,vobj,mode):
@@ -535,8 +558,8 @@ class _ViewProviderPrecast(ArchComponent.ViewProviderComponent):
import FreeCADGui
if hasattr(self,"dentd"):
self.Object.Dents = self.dentd.getValues()
del self.dentd
FreeCADGui.Control.closeDialog()
del self.dentd
return False
@@ -1042,7 +1065,7 @@ class _DentsTaskPanel:
return l
def makePrecast(precasttype,length=0,width=0,height=0,slabtype="",chamfer=0,dentlength=0,dentwidth=0,dentheight=0,dents=[],base=0,holenumber=0,holemajor=0,holeminor=0,holespacing=0,groovenumber=0,groovedepth=0,grooveheight=0,groovespacing=0):
def makePrecast(precasttype=None,length=0,width=0,height=0,slabtype="",chamfer=0,dentlength=0,dentwidth=0,dentheight=0,dents=[],base=0,holenumber=0,holemajor=0,holeminor=0,holespacing=0,groovenumber=0,groovedepth=0,grooveheight=0,groovespacing=0):
"creates one of the precast objects in the current document"

View File

@@ -504,6 +504,9 @@ class _ViewProviderStructure(ArchComponent.ViewProviderComponent):
def getIcon(self):
import Arch_rc
if hasattr(self,"Object"):
if self.Object.CloneOf:
return ":/icons/Arch_Structure_Clone.svg"
return ":/icons/Arch_Structure_Tree.svg"
def updateData(self,obj,prop):

View File

@@ -716,8 +716,7 @@ class _Window(ArchComponent.Component):
base = self.processSubShapes(obj,base)
if base:
if not base.isNull():
if base.Solids:
self.applyShape(obj,base,pl)
self.applyShape(obj,base,pl,allowinvalid=True,allownosolid=True)
def getSubVolume(self,obj,plac=None):
"returns a subvolume for cutting in a base object"
@@ -746,7 +745,10 @@ class _Window(ArchComponent.Component):
width = max(b.XLength,b.YLength,b.ZLength)
if not width:
if Draft.isClone(obj,"Window"):
orig = obj.Objects[0]
if hasattr(obj,"CloneOf"):
orig = obj.CloneOf
else:
orig = obj.Objects[0]
if orig.Base:
base = orig.Base
if hasattr(orig,"HoleDepth"):

View File

@@ -21,6 +21,7 @@
<file>icons/Arch_SectionPlane_Tree.svg</file>
<file>icons/Arch_Site_Tree.svg</file>
<file>icons/Arch_Structure_Tree.svg</file>
<file>icons/Arch_Structure_Clone.svg</file>
<file>icons/Arch_Window_Tree.svg</file>
<file>icons/Arch_Axis.svg</file>
<file>icons/Arch_Axis_Tree.svg</file>

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 18 KiB

View File

@@ -1116,32 +1116,75 @@ def export(exportList,filename):
sites = []
buildings = []
floors = []
treated = []
for floor in Draft.getObjectsOfType(objectslist,"Floor"):
objs = Draft.getGroupContents(floor,walls=True)
objs = Arch.pruneIncluded(objs)
children = []
for c in objs:
if c.Name in products.keys():
if not (c.Name in treated):
children.append(products[c.Name])
f = products[floor.Name]
if children:
ifcfile.createIfcRelContainedInSpatialStructure(ifcopenshell.guid.compress(uuid.uuid1().hex),history,'StoreyLink','',children,f)
floors.append(floor.Name)
for c in children:
if not (c.Name in treated):
treated.append(c.Name)
for building in Draft.getObjectsOfType(objectslist,"Building"):
objs = Draft.getGroupContents(building,walls=True)
objs = Arch.pruneIncluded(objs)
children = []
childfloors = []
for c in objs:
if c.Name in products.keys():
if Draft.getType(c) == "Floor":
childfloors.append(products[c.Name])
elif not (c.Name in treated):
children.append(products[c.Name])
b = products[building.Name]
if children:
ifcfile.createIfcRelContainedInSpatialStructure(ifcopenshell.guid.compress(uuid.uuid1().hex),history,'BuildingLink','',children,b)
if childfloors:
ifcfile.createIfcRelAggregates(ifcopenshell.guid.compress(uuid.uuid1().hex),history,'BuildingLink','',b,childfloors)
buildings.append(b)
for c in children+childfloors:
if not (c.Name in treated):
treated.append(c.Name)
for site in Draft.getObjectsOfType(objectslist,"Site"):
for building in Draft.getObjectsOfType(site.Group,"Building"):
for floor in Draft.getObjectsOfType(building.Group,"Floor"):
children = Draft.getGroupContents(floor,walls=True)
children = Arch.pruneIncluded(children)
children = [products[c.Name] for c in children if c.Name in products.keys()]
floor = products[floor.Name]
ifcfile.createIfcRelContainedInSpatialStructure(ifcopenshell.guid.compress(uuid.uuid1().hex),history,'StoreyLink','',children,floor)
floors.append(floor)
building = products[building.Name]
if floors:
ifcfile.createIfcRelAggregates(ifcopenshell.guid.compress(uuid.uuid1().hex),history,'BuildingLink','',building,floors)
buildings.append(building)
site = products[site.Name]
if buildings:
ifcfile.createIfcRelAggregates(ifcopenshell.guid.compress(uuid.uuid1().hex),history,'SiteLink','',site,buildings)
sites.append(site)
objs = Draft.getGroupContents(site,walls=True)
objs = Arch.pruneIncluded(objs)
children = []
childbuildings = []
for c in objs:
if c.Name in products.keys():
if Draft.getType(c) == "Building":
childbuildings.append(products[c.Name])
elif not (c.Name in treated):
children.append(products[c.Name])
s = products[site.Name]
if children:
ifcfile.createIfcRelContainedInSpatialStructure(ifcopenshell.guid.compress(uuid.uuid1().hex),history,'BuildingLink','',children,s)
sites.append(s)
for c in children+childbuildings:
if not (c.Name in treated):
treated.append(c.Name)
if not sites:
if DEBUG: print "adding default site"
if DEBUG: print "No site found. Adding default site"
sites = [ifcfile.createIfcSite(ifcopenshell.guid.compress(uuid.uuid1().hex),history,"Default Site",'',None,None,None,None,"ELEMENT",None,None,None,None,None)]
ifcfile.createIfcRelAggregates(ifcopenshell.guid.compress(uuid.uuid1().hex),history,'ProjectLink','',project,sites)
if not buildings:
if DEBUG: print "adding default building"
if DEBUG: print "No building found. Adding default building"
buildings = [ifcfile.createIfcBuilding(ifcopenshell.guid.compress(uuid.uuid1().hex),history,"Default Building",'',None,None,None,None,"ELEMENT",None,None,None)]
ifcfile.createIfcRelAggregates(ifcopenshell.guid.compress(uuid.uuid1().hex),history,'SiteLink','',sites[0],buildings)
ifcfile.createIfcRelContainedInSpatialStructure(ifcopenshell.guid.compress(uuid.uuid1().hex),history,'BuildingLink','',products.values(),buildings[0])
ifcfile.createIfcRelAggregates(ifcopenshell.guid.compress(uuid.uuid1().hex),history,'SiteLink','',sites[0],buildings)
untreated = []
for p in products.values():
if not(p.Name) in treated:
if p.Name != buildings[0].Name:
untreated.append(p)
if untreated:
ifcfile.createIfcRelContainedInSpatialStructure(ifcopenshell.guid.compress(uuid.uuid1().hex),history,'BuildingLink','',untreated,buildings[0])
# materials
materials = {}
@@ -1383,6 +1426,11 @@ def getRepresentation(ifcfile,context,obj,forcebrep=False,subtraction=False,tess
dataset = fcshape.Shells
if DEBUG: print "Warning! object contains no solids"
# if this is a clone, place back the shapes in null position
if tostore:
for shape in dataset:
shape.Placement = FreeCAD.Placement()
# new ifcopenshell serializer
from ifcopenshell import geom
if hasattr(geom,"serialise") and obj.isDerivedFrom("Part::Feature") and SERIALIZE:
@@ -1477,7 +1525,7 @@ def getRepresentation(ifcfile,context,obj,forcebrep=False,subtraction=False,tess
ovc = ifcfile.createIfcCartesianPoint((0.0,0.0,0.0))
gpl = ifcfile.createIfcAxis2Placement3D(ovc,zvc,xvc)
repmap = ifcfile.createIfcRepresentationMap(gpl,subrep)
pla = FreeCAD.ActiveDocument.getObject(k).Placement
pla = FreeCAD.ActiveDocument.getObject(tostore).Placement
axis1 = ifcfile.createIfcDirection(tuple(pla.Rotation.multVec(FreeCAD.Vector(1,0,0))))
axis2 = ifcfile.createIfcDirection(tuple(pla.Rotation.multVec(FreeCAD.Vector(0,1,0))))
origin = ifcfile.createIfcCartesianPoint(tuple(FreeCAD.Vector(pla.Base).multiply(0.001)))
@@ -1485,7 +1533,7 @@ def getRepresentation(ifcfile,context,obj,forcebrep=False,subtraction=False,tess
transf = ifcfile.createIfcCartesianTransformationOperator3D(axis1,axis2,origin,1.0,axis3)
mapitem = ifcfile.createIfcMappedItem(repmap,transf)
shapes = [mapitem]
sharedobjects[k] = repmap
sharedobjects[tostore] = repmap
solidType = "MappedRepresentation"
# set surface style

View File

@@ -2477,6 +2477,7 @@ def clone(obj,delta=None):
base = getCloneBase(obj[0])
cl.Label = prefix + base.Label
cl.CloneOf = base
cl.Placement = obj[0].Placement
return cl
else:
cl = FreeCAD.ActiveDocument.addObject("Part::AttachableObjectPython","Clone")