diff --git a/src/Mod/Arch/ArchCommands.py b/src/Mod/Arch/ArchCommands.py
index d70807cf536e..0171aa38d6a9 100644
--- a/src/Mod/Arch/ArchCommands.py
+++ b/src/Mod/Arch/ArchCommands.py
@@ -208,6 +208,10 @@ def makeComponent(baseobj=None,name="Component",delete=False):
obj.Placement = baseobj.Placement
if delete:
FreeCAD.ActiveDocument.removeObject(baseobj.Name)
+ else:
+ obj.Base = baseobj
+ if FreeCAD.GuiUp:
+ baseobj.ViewObject.hide()
elif isinstance(baseobj,Part.Shape):
obj.Shape = baseobj
return obj
@@ -897,7 +901,45 @@ def rebuildArchShape(objects=None):
print "Failed"
FreeCAD.ActiveDocument.recompute()
+
+def getExtrusionData(shape):
+ """getExtrusionData(shape): returns a base face and an extrusion vector
+ if this shape can be described as a perpendicular extrusion, or None if not."""
+ if shape.isNull():
+ return None
+ if not shape.Solids:
+ return None
+ if len(shape.Faces) < 5:
+ return None
+ # build faces list with normals
+ faces = []
+ for f in shape.Faces:
+ faces.append([f,f.normalAt(0,0)])
+ # find opposite normals pairs
+ pairs = []
+ for i1, f1 in enumerate(faces):
+ for i2, f2 in enumerate(faces):
+ if f1[0].hashCode() != f2[0].hashCode():
+ if round(f1[1].getAngle(f2[1]),8) == 3.14159265:
+ pairs.append([i1,i2])
+ if not pairs:
+ return None
+ for p in pairs:
+ hc = [faces[p[0]][0].hashCode(),faces[p[1]][0].hashCode()]
+ ok = True
+ # check if other normals are all at 90 degrees
+ for f in faces:
+ if f[0].hashCode() not in hc:
+ if round(f[1].getAngle(faces[p[0]][1]),8) != 1.57079633:
+ ok = False
+ if ok:
+ return [faces[p[0]][0],faces[p[1]][0].CenterOfMass.sub(faces[p[0]][0].CenterOfMass)]
+ return None
+
+
# command definitions ###############################################
+
+
class _CommandAdd:
"the Arch Add command definition"
def GetResources(self):
@@ -1053,6 +1095,7 @@ def Activated(self):
for o in sel:
FreeCADGui.Selection.addSelection(o)
+
class _CommandRemoveShape:
"the Arch RemoveShape command definition"
def GetResources(self):
@@ -1067,6 +1110,7 @@ def Activated(self):
sel = FreeCADGui.Selection.getSelection()
removeShape(sel)
+
class _CommandCloseHoles:
"the Arch CloseHoles command definition"
def GetResources(self):
@@ -1083,6 +1127,7 @@ def Activated(self):
if s:
o.Shape = s
+
class _CommandCheck:
"the Arch Check command definition"
def GetResources(self):
@@ -1146,8 +1191,8 @@ def IsActive(self):
def Activated(self):
for o in FreeCADGui.Selection.getSelection():
toggleIfcBrepFlag(o)
-
-
+
+
class _CommandComponent:
"the Arch Component command definition"
def GetResources(self):
diff --git a/src/Mod/Arch/ArchComponent.py b/src/Mod/Arch/ArchComponent.py
index 921bebb03eb3..dd93a88dddfd 100644
--- a/src/Mod/Arch/ArchComponent.py
+++ b/src/Mod/Arch/ArchComponent.py
@@ -306,7 +306,8 @@ def __init__(self,obj):
obj.Role = Roles
def execute(self,obj):
- return
+ if obj.Base:
+ obj.Shape = obj.Base.Shape
def __getstate__(self):
return self.Type
@@ -378,7 +379,13 @@ def getProfiles(self,obj,noplacement=False):
wires = []
n,l,w,h = self.getDefaultValues(obj)
if obj.Base:
- if obj.Base.isDerivedFrom("Part::Feature"):
+ if obj.Base.isDerivedFrom("Part::Extrusion"):
+ if obj.Base.Base:
+ base = obj.Base.Base.Shape.copy()
+ if noplacement:
+ base.Placement = FreeCAD.Placement()
+ return [base]
+ elif obj.Base.isDerivedFrom("Part::Feature"):
if obj.Base.Shape:
base = obj.Base.Shape.copy()
if noplacement:
@@ -469,6 +476,9 @@ def getProfiles(self,obj,noplacement=False):
def getExtrusionVector(self,obj,noplacement=False):
"Returns an extrusion vector of this component, if applicable"
n,l,w,h = self.getDefaultValues(obj)
+ if obj.Base:
+ if obj.Base.isDerivedFrom("Part::Extrusion"):
+ return obj.Base.Dir
if Draft.getType(obj) == "Structure":
if l > h:
v = n.multiply(l)
diff --git a/src/Mod/Arch/Resources/ui/archprefs-import.ui b/src/Mod/Arch/Resources/ui/archprefs-import.ui
index 3d311aa0b5e6..ff3472389f1e 100644
--- a/src/Mod/Arch/Resources/ui/archprefs-import.ui
+++ b/src/Mod/Arch/Resources/ui/archprefs-import.ui
@@ -137,6 +137,26 @@
+ -
+
+
-
+
+
+ If this is checked, the importer will try to detect extrusions. This might slow things down...
+
+
+ Detect extrusions
+
+
+ ifcGetExtrusions
+
+
+ Mod/Arch
+
+
+
+
+
-
-
diff --git a/src/Mod/Arch/importIFC.py b/src/Mod/Arch/importIFC.py
index 16d573e44e7d..2f83d198be95 100644
--- a/src/Mod/Arch/importIFC.py
+++ b/src/Mod/Arch/importIFC.py
@@ -270,11 +270,13 @@ def insert(filename,docname,skip=[],only=[],root=None):
SKIP = p.GetString("ifcSkip","").split(",")
SEPARATE_OPENINGS = p.GetBool("ifcSeparateOpenings",False)
ROOT_ELEMENT = p.GetString("ifcRootElement","IfcProduct")
+ GET_EXTRUSIONS = p.GetBool("ifcGetExtrusions",False)
if root:
ROOT_ELEMENT = root
MERGE_MODE = p.GetInt("ifcImportMode",0)
if MERGE_MODE > 0:
SEPARATE_OPENINGS = False
+ GET_EXTRUSIONS = False
if not SEPARATE_OPENINGS:
SKIP.append("IfcOpeningElement")
@@ -418,13 +420,25 @@ def insert(filename,docname,skip=[],only=[],root=None):
if DEBUG: print shape.Solids
baseobj = shape
else:
- baseobj = FreeCAD.ActiveDocument.addObject("Part::Feature",name+"_body")
- baseobj.Shape = shape
+ if GET_EXTRUSIONS:
+ ex = Arch.getExtrusionData(shape)
+ if ex:
+ print "extrusion ",
+ baseface = FreeCAD.ActiveDocument.addObject("Part::Feature",name+"_footprint")
+ baseface.Shape = ex[0]
+ baseobj = FreeCAD.ActiveDocument.addObject("Part::Extrusion",name+"_body")
+ baseobj.Base = baseface
+ baseobj.Dir = ex[1]
+ if FreeCAD.GuiUp:
+ baseface.ViewObject.hide()
+ if not baseobj:
+ baseobj = FreeCAD.ActiveDocument.addObject("Part::Feature",name+"_body")
+ baseobj.Shape = shape
else:
if DEBUG: print "null shape ",
if not shape.isValid():
- if DEBUG: print "invalid shape. Skipping"
- continue
+ if DEBUG: print "invalid shape ",
+ #continue
else:
if DEBUG: print " no brep ",
@@ -436,6 +450,8 @@ def insert(filename,docname,skip=[],only=[],root=None):
if ptype in ifctypes:
obj = getattr(Arch,"make"+freecadtype)(baseobj=baseobj,name=name)
obj.Label = name
+ if FreeCAD.GuiUp and baseobj:
+ baseobj.ViewObject.hide()
# setting role
try:
r = ptype[3:]
@@ -455,7 +471,7 @@ def insert(filename,docname,skip=[],only=[],root=None):
obj.IfcAttributes = a
break
if not obj:
- obj = Arch.makeComponent(baseobj,name=name,delete=True)
+ obj = Arch.makeComponent(baseobj,name=name)
if obj:
sols = str(obj.Shape.Solids) if hasattr(obj,"Shape") else "[]"
if DEBUG: print sols
@@ -469,7 +485,7 @@ def insert(filename,docname,skip=[],only=[],root=None):
if ptype in ifctypes:
obj = getattr(Arch,"make"+freecadtype)(baseobj=None,name=name)
elif baseobj:
- obj = Arch.makeComponent(baseobj,name=name)
+ obj = Arch.makeComponent(baseobj,name=name,delete=True)
elif MERGE_MODE == 2:
@@ -545,7 +561,7 @@ def insert(filename,docname,skip=[],only=[],root=None):
if SEPARATE_OPENINGS:
for subtraction in subtractions:
if (subtraction[0] in objects.keys()) and (subtraction[1] in objects.keys()):
- if DEBUG: print "subtracting ",objects[subtraction[0]].Name, " from ", objects[subtraction[1]].Name
+ if DEBUG: print "subtracting ",objects[subtraction[0]].Label, " from ", objects[subtraction[1]].Label
Arch.removeComponents(objects[subtraction[0]],objects[subtraction[1]])
if DEBUG: FreeCAD.ActiveDocument.recompute()
@@ -558,14 +574,12 @@ def insert(filename,docname,skip=[],only=[],root=None):
# avoid huge fusions
print "more than 10 shapes to add: skipping."
else:
- if DEBUG: print "adding ",cobs, " to ", objects[host].Name
+ if DEBUG: print "adding ",len(cobs), " object(s) to ", objects[host].Label
Arch.addComponents(cobs,objects[host])
if DEBUG: FreeCAD.ActiveDocument.recompute()
FreeCAD.ActiveDocument.recompute()
- if DEBUG: print "Cleaning..."
-
# cleaning bad shapes
for obj in objects.values():
if obj.isDerivedFrom("Part::Feature"):