Arch: Faster material handling in IFC import - fixes #2762

This commit is contained in:
Yorik van Havre 2016-12-29 16:05:52 -02:00
parent 3114df352d
commit 0249235833
3 changed files with 70 additions and 39 deletions

View File

@ -392,9 +392,11 @@ class Component:
if obj.Base.isDerivedFrom("Part::Extrusion"): if obj.Base.isDerivedFrom("Part::Extrusion"):
if obj.Base.Base: if obj.Base.Base:
base,placement = self.rebase(obj.Base.Base.Shape) base,placement = self.rebase(obj.Base.Base.Shape)
extrusion = obj.Base.Dir extrusion = FreeCAD.Vector(obj.Base.Dir)
if extrusion.Length == 0: if extrusion.Length == 0:
extrusion = FreeCAD.Vector(0,0,1) extrusion = FreeCAD.Vector(0,0,1)
else:
extrusion = placement.inverse().Rotation.multVec(extrusion)
if hasattr(obj.Base,"LengthForward"): if hasattr(obj.Base,"LengthForward"):
if obj.Base.LengthForward.Value: if obj.Base.LengthForward.Value:
extrusion = extrusion.multiply(obj.Base.LengthForward.Value) extrusion = extrusion.multiply(obj.Base.LengthForward.Value)

View File

@ -377,10 +377,11 @@ def insert(filename,docname,skip=[],only=[],root=None):
annotations = ifcfile.by_type("IfcAnnotation") annotations = ifcfile.by_type("IfcAnnotation")
materials = ifcfile.by_type("IfcMaterial") materials = ifcfile.by_type("IfcMaterial")
if DEBUG: print "Building relationships table...", if DEBUG: print "Building relationships tables...",
# building relations tables # building relations tables
objects = {} # { id:object, ... } objects = {} # { id:object, ... }
prodrepr = {} # product/representations table
additions = {} # { host:[child,...], ... } additions = {} # { host:[child,...], ... }
groups = {} # { host:[child,...], ... } # used in structural IFC groups = {} # { host:[child,...], ... } # used in structural IFC
subtractions = [] # [ [opening,host], ... ] subtractions = [] # [ [opening,host], ... ]
@ -418,6 +419,19 @@ def insert(filename,docname,skip=[],only=[],root=None):
mattable[o.id()] = r.RelatingMaterial.MaterialLayers[0].Material.id() mattable[o.id()] = r.RelatingMaterial.MaterialLayers[0].Material.id()
elif r.RelatingMaterial.is_a("IfcMaterialLayerSetUsage"): elif r.RelatingMaterial.is_a("IfcMaterialLayerSetUsage"):
mattable[o.id()] = r.RelatingMaterial.ForLayerSet.MaterialLayers[0].Material.id() mattable[o.id()] = r.RelatingMaterial.ForLayerSet.MaterialLayers[0].Material.id()
for p in ifcfile.by_type("IfcProduct"):
if hasattr(p,"Representation"):
if p.Representation:
for it in p.Representation.Representations:
for it1 in it.Items:
prodrepr.setdefault(p.id(),[]).append(it1.id())
if it1.is_a("IfcBooleanResult"):
prodrepr.setdefault(p.id(),[]).append(it1.FirstOperand.id())
elif it.Items[0].is_a("IfcMappedItem"):
prodrepr.setdefault(p.id(),[]).append(it1.MappingSource.MappedRepresentation.id())
if it1.MappingSource.MappedRepresentation.is_a("IfcShapeRepresentation"):
for it2 in it1.MappingSource.MappedRepresentation.Items:
prodrepr.setdefault(p.id(),[]).append(it2.id())
for r in ifcfile.by_type("IfcStyledItem"): for r in ifcfile.by_type("IfcStyledItem"):
if r.Styles: if r.Styles:
if r.Styles[0].is_a("IfcPresentationStyleAssignment"): if r.Styles[0].is_a("IfcPresentationStyleAssignment"):
@ -426,16 +440,9 @@ def insert(filename,docname,skip=[],only=[],root=None):
if r.Styles[0].Styles[0].Styles[0].SurfaceColour: if r.Styles[0].Styles[0].Styles[0].SurfaceColour:
c = r.Styles[0].Styles[0].Styles[0].SurfaceColour c = r.Styles[0].Styles[0].Styles[0].SurfaceColour
if r.Item: if r.Item:
for p in ifcfile.by_type("IfcProduct"): for p in prodrepr.keys():
if hasattr(p,"Representation"): if r.Item.id() in prodrepr[p]:
if p.Representation: colors[p] = (c.Red,c.Green,c.Blue)
for it in p.Representation.Representations:
if it.Items:
if it.Items[0].id() == r.Item.id():
colors[p.id()] = (c.Red,c.Green,c.Blue)
elif it.Items[0].is_a("IfcBooleanResult"):
if (it.Items[0].FirstOperand.id() == r.Item.id()):
colors[p.id()] = (c.Red,c.Green,c.Blue)
else: else:
for m in ifcfile.by_type("IfcMaterialDefinitionRepresentation"): for m in ifcfile.by_type("IfcMaterialDefinitionRepresentation"):
for it in m.Representations: for it in m.Representations:
@ -720,7 +727,7 @@ def insert(filename,docname,skip=[],only=[],root=None):
# if DEBUG is on, recompute after each shape # if DEBUG is on, recompute after each shape
if DEBUG: FreeCAD.ActiveDocument.recompute() if DEBUG: FreeCAD.ActiveDocument.recompute()
# attached 2D elements # attached 2D elements
if product.Representation: if product.Representation:
for r in product.Representation.Representations: for r in product.Representation.Representations:
@ -736,7 +743,7 @@ def insert(filename,docname,skip=[],only=[],root=None):
if MERGE_MODE_STRUCT == 2: if MERGE_MODE_STRUCT == 2:
if DEBUG: print "Joining Structural shapes..." if DEBUG: print "Joining Structural shapes...",
for host,children in groups.items(): # Structural for host,children in groups.items(): # Structural
if ifcfile[host].is_a("IfcStructuralAnalysisModel"): if ifcfile[host].is_a("IfcStructuralAnalysisModel"):
@ -754,9 +761,12 @@ def insert(filename,docname,skip=[],only=[],root=None):
if structshapes: # remaining Structural shapes if structshapes: # remaining Structural shapes
obj = FreeCAD.ActiveDocument.addObject("Part::Feature","UnclaimedStruct") obj = FreeCAD.ActiveDocument.addObject("Part::Feature","UnclaimedStruct")
obj.Shape = Part.makeCompound(structshapes.values()) obj.Shape = Part.makeCompound(structshapes.values())
if DEBUG: print "done"
else: else:
if DEBUG: print "Processing Struct relationships..." if DEBUG: print "Processing Struct relationships...",
# groups # groups
for host,children in groups.items(): for host,children in groups.items():
@ -778,6 +788,8 @@ def insert(filename,docname,skip=[],only=[],root=None):
Arch.addComponents(cobs,objects[host]) Arch.addComponents(cobs,objects[host])
if DEBUG: FreeCAD.ActiveDocument.recompute() if DEBUG: FreeCAD.ActiveDocument.recompute()
if DEBUG: print "done"
if MERGE_MODE_ARCH > 2: # if ArchObj is compound or ArchObj not imported if MERGE_MODE_ARCH > 2: # if ArchObj is compound or ArchObj not imported
FreeCAD.ActiveDocument.recompute() FreeCAD.ActiveDocument.recompute()
@ -805,7 +817,7 @@ def insert(filename,docname,skip=[],only=[],root=None):
if MERGE_MODE_ARCH == 3: if MERGE_MODE_ARCH == 3:
if DEBUG: print "Joining Arch shapes..." if DEBUG: print "Joining Arch shapes...",
for host,children in additions.items(): # Arch for host,children in additions.items(): # Arch
if ifcfile[host].is_a("IfcBuildingStorey"): if ifcfile[host].is_a("IfcBuildingStorey"):
@ -829,6 +841,8 @@ def insert(filename,docname,skip=[],only=[],root=None):
obj = FreeCAD.ActiveDocument.addObject("Part::Feature","UnclaimedArch") obj = FreeCAD.ActiveDocument.addObject("Part::Feature","UnclaimedArch")
obj.Shape = Part.makeCompound(shapes.values()) obj.Shape = Part.makeCompound(shapes.values())
if DEBUG: print "done"
else: else:
if DEBUG: print "Processing Arch relationships..." if DEBUG: print "Processing Arch relationships..."
@ -859,7 +873,7 @@ def insert(filename,docname,skip=[],only=[],root=None):
# cleaning bad shapes # cleaning bad shapes
for obj in objects.values(): for obj in objects.values():
if obj.isDerivedFrom("Part::Feature"): if obj.isDerivedFrom("Part::Feature"):
if obj.Shape.isNull(): if obj.Shape.isNull() and not(Draft.getType(obj) in ["Site"]):
Arch.rebuildArchShape(obj) Arch.rebuildArchShape(obj)
FreeCAD.ActiveDocument.recompute() FreeCAD.ActiveDocument.recompute()
@ -893,16 +907,16 @@ def insert(filename,docname,skip=[],only=[],root=None):
p = getPlacement(annotation.ObjectPlacement,scaling) p = getPlacement(annotation.ObjectPlacement,scaling)
if p: # and annotation.is_a("IfcAnnotation"): if p: # and annotation.is_a("IfcAnnotation"):
o.Placement = p o.Placement = p
count += 1 count += 1
FreeCAD.ActiveDocument.recompute() FreeCAD.ActiveDocument.recompute()
# Materials # Materials
if DEBUG and materials: print "Creating materials..." if DEBUG and materials: print "Creating materials...",
print "mattable:",mattable #print "mattable:",mattable
print "materials:",materials #print "materials:",materials
fcmats = {} fcmats = {}
for material in materials: for material in materials:
name = "Material" name = "Material"
@ -914,7 +928,12 @@ def insert(filename,docname,skip=[],only=[],root=None):
mat = Arch.makeMaterial(name=name) mat = Arch.makeMaterial(name=name)
mdict = {} mdict = {}
if material.id() in colors: if material.id() in colors:
mdict["Color"] = str(colors[material.id()]) mdict["DiffuseColor"] = str(colors[material.id()])
else:
for o,m in mattable.items():
if m == material.id():
if o in colors:
mdict["DiffuseColor"] = str(colors[o])
if mdict: if mdict:
mat.Material = mdict mat.Material = mdict
fcmats[name] = mat fcmats[name] = mat
@ -924,6 +943,8 @@ def insert(filename,docname,skip=[],only=[],root=None):
if hasattr(objects[o],"BaseMaterial"): if hasattr(objects[o],"BaseMaterial"):
objects[o].BaseMaterial = mat objects[o].BaseMaterial = mat
if DEBUG and materials: print "done"
FreeCAD.ActiveDocument.recompute() FreeCAD.ActiveDocument.recompute()
if FreeCAD.GuiUp: if FreeCAD.GuiUp:
@ -986,7 +1007,7 @@ def export(exportList,filename):
annotations.append(obj) annotations.append(obj)
elif obj.isDerivedFrom("Part::Feature"): elif obj.isDerivedFrom("Part::Feature"):
if obj.Shape: if obj.Shape:
if not obj.Shape.Faces: if obj.Shape.Edges and (not obj.Shape.Faces):
annotations.append(obj) annotations.append(obj)
objectslist = Arch.pruneIncluded(objectslist) objectslist = Arch.pruneIncluded(objectslist)
products = {} # { Name: IfcEntity, ... } products = {} # { Name: IfcEntity, ... }
@ -1328,7 +1349,7 @@ def export(exportList,filename):
ass = ifcfile.createIfcRelAssignsToGroup(ifcopenshell.guid.compress(uuid.uuid1().hex),history,'GroupLink','',children,None,grp) ass = ifcfile.createIfcRelAssignsToGroup(ifcopenshell.guid.compress(uuid.uuid1().hex),history,'GroupLink','',children,None,grp)
# 2D objects # 2D objects
if EXPORT_2D: if EXPORT_2D:
curvestyles = {} curvestyles = {}
if annotations and DEBUG: print "exporting 2D objects..." if annotations and DEBUG: print "exporting 2D objects..."
@ -1355,7 +1376,7 @@ def export(exportList,filename):
tpl = ifcfile.createIfcAxis2Placement3D(pos,None,None) tpl = ifcfile.createIfcAxis2Placement3D(pos,None,None)
txt = ifcfile.createIfcTextLiteral(";".join(anno.LabelText).encode("utf8"),tpl,"LEFT") txt = ifcfile.createIfcTextLiteral(";".join(anno.LabelText).encode("utf8"),tpl,"LEFT")
reps = [txt] reps = [txt]
for coldef in ["LineColor","TextColor","ShapeColor"]: for coldef in ["LineColor","TextColor","ShapeColor"]:
if hasattr(obj.ViewObject,coldef): if hasattr(obj.ViewObject,coldef):
rgb = getattr(obj.ViewObject,coldef)[:3] rgb = getattr(obj.ViewObject,coldef)[:3]
@ -1370,11 +1391,11 @@ def export(exportList,filename):
for rep in reps: for rep in reps:
isi = ifcfile.createIfcStyledItem(rep,[psa],None) isi = ifcfile.createIfcStyledItem(rep,[psa],None)
break break
shp = ifcfile.createIfcShapeRepresentation(context,'Annotation','Annotation2D',reps) shp = ifcfile.createIfcShapeRepresentation(context,'Annotation','Annotation2D',reps)
rep = ifcfile.createIfcProductDefinitionShape(None,None,[shp]) rep = ifcfile.createIfcProductDefinitionShape(None,None,[shp])
ann = ifcfile.createIfcAnnotation(ifcopenshell.guid.compress(uuid.uuid1().hex),history,anno.Label.encode('utf8'),'',None,gpl,rep) ann = ifcfile.createIfcAnnotation(ifcopenshell.guid.compress(uuid.uuid1().hex),history,anno.Label.encode('utf8'),'',None,gpl,rep)
if DEBUG: print "writing ",filename,"..." if DEBUG: print "writing ",filename,"..."
filename = decode(filename) filename = decode(filename)
@ -1384,13 +1405,13 @@ def export(exportList,filename):
if STORE_UID: if STORE_UID:
# some properties might have been changed # some properties might have been changed
FreeCAD.ActiveDocument.recompute() FreeCAD.ActiveDocument.recompute()
os.remove(templatefile) os.remove(templatefile)
def createCurve(ifcfile,wire): def createCurve(ifcfile,wire):
"creates an IfcCompositeCurve from a shape" "creates an IfcCompositeCurve from a shape"
segments = [] segments = []
pol = None pol = None
last = None last = None
@ -1593,12 +1614,12 @@ def getRepresentation(ifcfile,context,obj,forcebrep=False,subtraction=False,tess
else: else:
dataset = fcshape.Shells dataset = fcshape.Shells
#if DEBUG: print "Warning! object contains no solids" #if DEBUG: print "Warning! object contains no solids"
# if this is a clone, place back the shapes in null position # if this is a clone, place back the shapes in null position
if tostore: if tostore:
for shape in dataset: for shape in dataset:
shape.Placement = FreeCAD.Placement() shape.Placement = FreeCAD.Placement()
for fcsolid in dataset: for fcsolid in dataset:
fcsolid.scale(0.001) # to meters fcsolid.scale(0.001) # to meters
faces = [] faces = []
@ -1637,7 +1658,7 @@ def getRepresentation(ifcfile,context,obj,forcebrep=False,subtraction=False,tess
face = ifcfile.createIfcFace([bound]) face = ifcfile.createIfcFace([bound])
faces.append(face) faces.append(face)
fcsolid = Part.Shape() # empty shape so below code is not executed fcsolid = Part.Shape() # empty shape so below code is not executed
for fcface in fcsolid.Faces: for fcface in fcsolid.Faces:
loops = [] loops = []
verts = [v.Point for v in fcface.OuterWire.OrderedVertexes] verts = [v.Point for v in fcface.OuterWire.OrderedVertexes]
@ -1664,12 +1685,12 @@ def getRepresentation(ifcfile,context,obj,forcebrep=False,subtraction=False,tess
loops.append(bound) loops.append(bound)
face = ifcfile.createIfcFace(loops) face = ifcfile.createIfcFace(loops)
faces.append(face) faces.append(face)
if faces: if faces:
shell = ifcfile.createIfcClosedShell(faces) shell = ifcfile.createIfcClosedShell(faces)
shape = ifcfile.createIfcFacetedBrep(shell) shape = ifcfile.createIfcFacetedBrep(shell)
shapes.append(shape) shapes.append(shape)
shapedefs[shapedef] = shapes shapedefs[shapedef] = shapes
if shapes: if shapes:
@ -1746,7 +1767,7 @@ def setRepresentation(representation,scaling=1000):
c.multiply(scaling) c.multiply(scaling)
r = ent.Radius*scaling r = ent.Radius*scaling
return Part.makeCircle(r,c) return Part.makeCircle(r,c)
def getCurveSet(ent): def getCurveSet(ent):
result = [] result = []
for el in ent.Elements: for el in ent.Elements:

View File

@ -330,7 +330,7 @@ def getGroupContents(objectslist,walls=False,addgroups=False):
objectslist = [objectslist] objectslist = [objectslist]
for obj in objectslist: for obj in objectslist:
if obj: if obj:
if obj.isDerivedFrom("App::DocumentObjectGroup") or ((getType(obj) == "Space") and hasattr(obj,"Group")): if obj.isDerivedFrom("App::DocumentObjectGroup") or ((getType(obj) in ["Space","Site"]) and hasattr(obj,"Group")):
if obj.isDerivedFrom("Drawing::FeaturePage"): if obj.isDerivedFrom("Drawing::FeaturePage"):
# skip if the group is a page # skip if the group is a page
newlist.append(obj) newlist.append(obj)
@ -1573,9 +1573,17 @@ def offset(obj,delta,copy=False,bind=False,sym=False,occ=False):
elif newwire: elif newwire:
newobj = FreeCAD.ActiveDocument.addObject("Part::Feature","Offset") newobj = FreeCAD.ActiveDocument.addObject("Part::Feature","Offset")
newobj.Shape = newwire newobj.Shape = newwire
else:
print("Draft.offset: Unable to duplicate this object")
elif getType(obj) == "Rectangle": elif getType(obj) == "Rectangle":
length,height,plac = getRect(p,obj) if p:
newobj = makeRectangle(length,height,plac) length,height,plac = getRect(p,obj)
newobj = makeRectangle(length,height,plac)
elif newwire:
newobj = FreeCAD.ActiveDocument.addObject("Part::Feature","Offset")
newobj.Shape = newwire
else:
print("Draft.offset: Unable to duplicate this object")
elif getType(obj) == "Circle": elif getType(obj) == "Circle":
pl = obj.Placement pl = obj.Placement
newobj = makeCircle(delta) newobj = makeCircle(delta)
@ -1603,7 +1611,7 @@ def offset(obj,delta,copy=False,bind=False,sym=False,occ=False):
newobj = FreeCAD.ActiveDocument.addObject("Part::Feature","Offset") newobj = FreeCAD.ActiveDocument.addObject("Part::Feature","Offset")
newobj.Shape = newwire newobj.Shape = newwire
else: else:
print("Unable to create an offset") print("Draft.offset: Unable to create an offset")
if newobj: if newobj:
formatObject(newobj,obj) formatObject(newobj,obj)
else: else: