diff --git a/src/Mod/Arch/ArchComponent.py b/src/Mod/Arch/ArchComponent.py index 766e911a3761..8d9797e9ffd0 100644 --- a/src/Mod/Arch/ArchComponent.py +++ b/src/Mod/Arch/ArchComponent.py @@ -703,9 +703,10 @@ def onChanged(self,vobj,prop): elif prop == "DiffuseColor": if hasattr(vobj.Object,"CloneOf"): if vobj.Object.CloneOf: - if vobj.DiffuseColor != vobj.Object.CloneOf.ViewObject.DiffuseColor: - vobj.DiffuseColor = vobj.Object.CloneOf.ViewObject.DiffuseColor - vobj.update() + if len(vobj.Object.CloneOf.ViewObject.DiffuseColor) > 1: + if vobj.DiffuseColor != vobj.Object.CloneOf.ViewObject.DiffuseColor: + vobj.DiffuseColor = vobj.Object.CloneOf.ViewObject.DiffuseColor + vobj.update() elif prop == "ShapeColor": # restore DiffuseColor after overridden by ShapeColor if len(vobj.DiffuseColor) > 1: diff --git a/src/Mod/Arch/importIFC.py b/src/Mod/Arch/importIFC.py index 4917043cac39..e7aeb533305c 100644 --- a/src/Mod/Arch/importIFC.py +++ b/src/Mod/Arch/importIFC.py @@ -165,6 +165,7 @@ def explore(filename=None): entities += ifc.by_type("IfcProperty") entities += ifc.by_type("IfcPhysicalSimpleQuantity") entities += ifc.by_type("IfcMaterial") + entities += ifc.by_type("IfcProductRepresentation") entities = sorted(entities, key=lambda eid: eid.id()) done = [] @@ -353,6 +354,7 @@ def insert(filename,docname,skip=[],only=[],root=None): shapes = {} # { id:shaoe } only used for merge mode structshapes = {} # { id:shaoe } only used for merge mode mattable = {} # { objid:matid } + sharedobjects = {} # { representationmapid:object } for r in ifcfile.by_type("IfcRelContainedInSpatialStructure"): additions.setdefault(r.RelatingStructure.id(),[]).extend([e.id() for e in r.RelatedElements]) for r in ifcfile.by_type("IfcRelAggregates"): @@ -406,6 +408,7 @@ def insert(filename,docname,skip=[],only=[],root=None): from FreeCAD import Base progressbar = Base.ProgressIndicator() progressbar.start("Importing IFC objects...",len(products)) + if DEBUG: print "Processing objects..." # products for product in products: @@ -413,7 +416,7 @@ def insert(filename,docname,skip=[],only=[],root=None): pid = product.id() guid = product.GlobalId ptype = product.is_a() - if DEBUG: print count,"/",len(products)," creating object ",pid," : ",ptype, + if DEBUG: print count+1,"/",len(products)," creating object #",pid," : ",ptype, name = str(ptype[3:]) if product.Name: name = product.Name.decode("unicode_escape").encode("utf8") @@ -421,13 +424,14 @@ def insert(filename,docname,skip=[],only=[],root=None): obj = None baseobj = None brep = None + shape = None archobj = True # assume all objects not in structuralifcobjects are architecture if ptype in structuralifcobjects: archobj = False - if DEBUG: print " : structural object :", + if DEBUG: print " (struct)", else: - if DEBUG: print " : architecture object :", + if DEBUG: print " (arch)", if MERGE_MODE_ARCH == 4 and archobj: if DEBUG: print " skipped." continue @@ -441,6 +445,20 @@ def insert(filename,docname,skip=[],only=[],root=None): if DEBUG: print " skipped." continue + # detect if this object is sharing its shape + clone = None + store = None + if product.Representation and MERGE_MODE_ARCH == 0 and archobj: + for s in product.Representation.Representations: + if s.RepresentationIdentifier.upper() == "BODY": + if s.Items[0].is_a("IfcMappedItem"): + bid = s.Items[0].MappingSource.id() + if bid in sharedobjects: + clone = sharedobjects[bid] + else: + sharedobjects[bid] = None + store = bid + try: cr = ifcopenshell.geom.create_shape(settings,product) brep = cr.geometry.brep_data @@ -461,27 +479,30 @@ def insert(filename,docname,skip=[],only=[],root=None): if DEBUG: print "skipping space ",pid elif not archobj: structshapes[pid] = shape - if DEBUG: print shape.Solids + if DEBUG: print shape.Solids," ", baseobj = shape else: shapes[pid] = shape - if DEBUG: print shape.Solids + if DEBUG: print shape.Solids," ", baseobj = shape else: - 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 + if clone: + if DEBUG: print "clone ", + else: + 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(): @@ -489,17 +510,29 @@ def insert(filename,docname,skip=[],only=[],root=None): #continue else: - if DEBUG: print " no brep \n", + if DEBUG: print " no brep ", - if MERGE_MODE_ARCH == 0 and archobj : + if MERGE_MODE_ARCH == 0 and archobj: # full Arch objects for freecadtype,ifctypes in typesmap.items(): if ptype in ifctypes: - obj = getattr(Arch,"make"+freecadtype)(baseobj=baseobj,name=name) + if clone: + obj = getattr(Arch,"make"+freecadtype)(name=name) + obj.CloneOf = clone + if shape: + v = shape.Solids[0].CenterOfMass.sub(clone.Shape.Solids[0].CenterOfMass) + p = FreeCAD.Placement(obj.Placement) + p.move(v) + obj.Placement = p + else: + obj = getattr(Arch,"make"+freecadtype)(baseobj=baseobj,name=name) + if store: + sharedobjects[store] = obj obj.Label = name if FreeCAD.GuiUp and baseobj: - baseobj.ViewObject.hide() + if hasattr(baseobj,"ViewObject"): + baseobj.ViewObject.hide() # setting role try: r = ptype[3:] @@ -521,7 +554,7 @@ def insert(filename,docname,skip=[],only=[],root=None): if not obj: obj = Arch.makeComponent(baseobj,name=name) if obj: - sols = str(obj.Shape.Solids) if hasattr(obj,"Shape") else "[]" + sols = str(obj.Shape.Solids) if hasattr(obj,"Shape") else "" if DEBUG: print sols objects[pid] = obj @@ -786,8 +819,16 @@ def export(exportList,filename): objectslist = Arch.pruneIncluded(objectslist) products = {} # { Name: IfcEntity, ... } surfstyles = {} # { (r,g,b): IfcEntity, ... } + clones = {} # { Basename:[Clonename1,Clonename2,...] } + sharedobjects = {} # { BaseName: IfcRepresentationMap } count = 1 + # build clones table + for o in objectlist: + b = Draft.getCloneBase(o,strict=True) + if b: + clones.setdefault(b.Name,[]).append(o.Name) + # products for obj in objectslist: diff --git a/src/Mod/Draft/Draft.py b/src/Mod/Draft/Draft.py index 1a339d5f7d9b..8d8f71b523d6 100644 --- a/src/Mod/Draft/Draft.py +++ b/src/Mod/Draft/Draft.py @@ -2463,14 +2463,17 @@ def clone(obj,delta=None): formatObject(cl,obj[0]) return cl -def getCloneBase(obj): - '''getCloneBase(obj): returns the object cloned by this object, if - any, or this object if it is no clone''' +def getCloneBase(obj,strict=False): + '''getCloneBase(obj,[strict]): returns the object cloned by this object, if + any, or this object if it is no clone. If strict is True, if this object is + not a clone, this function returns False''' if hasattr(obj,"CloneOf"): if obj.CloneOf: return getCloneBase(obj.CloneOf) if getType(obj) == "Clone": return obj.Objects[0] + if strict: + return False return obj def heal(objlist=None,delete=True,reparent=True):