diff --git a/src/Mod/Arch/ArchComponent.py b/src/Mod/Arch/ArchComponent.py
index c0e2e0887..91dfd7646 100644
--- a/src/Mod/Arch/ArchComponent.py
+++ b/src/Mod/Arch/ArchComponent.py
@@ -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")
diff --git a/src/Mod/Arch/ArchPrecast.py b/src/Mod/Arch/ArchPrecast.py
index af0a118d6..7fd758208 100644
--- a/src/Mod/Arch/ArchPrecast.py
+++ b/src/Mod/Arch/ArchPrecast.py
@@ -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"
diff --git a/src/Mod/Arch/ArchStructure.py b/src/Mod/Arch/ArchStructure.py
index 666faa3de..a551f1014 100644
--- a/src/Mod/Arch/ArchStructure.py
+++ b/src/Mod/Arch/ArchStructure.py
@@ -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):
diff --git a/src/Mod/Arch/ArchWindow.py b/src/Mod/Arch/ArchWindow.py
index f33cc691e..c23b6115b 100644
--- a/src/Mod/Arch/ArchWindow.py
+++ b/src/Mod/Arch/ArchWindow.py
@@ -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"):
diff --git a/src/Mod/Arch/Resources/Arch.qrc b/src/Mod/Arch/Resources/Arch.qrc
index 054d7e637..fbad062aa 100644
--- a/src/Mod/Arch/Resources/Arch.qrc
+++ b/src/Mod/Arch/Resources/Arch.qrc
@@ -21,6 +21,7 @@
icons/Arch_SectionPlane_Tree.svg
icons/Arch_Site_Tree.svg
icons/Arch_Structure_Tree.svg
+ icons/Arch_Structure_Clone.svg
icons/Arch_Window_Tree.svg
icons/Arch_Axis.svg
icons/Arch_Axis_Tree.svg
diff --git a/src/Mod/Arch/Resources/icons/Arch_Structure_Clone.svg b/src/Mod/Arch/Resources/icons/Arch_Structure_Clone.svg
new file mode 100644
index 000000000..3b9f2659c
--- /dev/null
+++ b/src/Mod/Arch/Resources/icons/Arch_Structure_Clone.svg
@@ -0,0 +1,288 @@
+
+
+
+
diff --git a/src/Mod/Arch/importIFC.py b/src/Mod/Arch/importIFC.py
index d29a7cb92..f8468ec6d 100644
--- a/src/Mod/Arch/importIFC.py
+++ b/src/Mod/Arch/importIFC.py
@@ -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
diff --git a/src/Mod/Draft/Draft.py b/src/Mod/Draft/Draft.py
index 138bbdc82..6e77a2e73 100644
--- a/src/Mod/Draft/Draft.py
+++ b/src/Mod/Draft/Draft.py
@@ -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")