diff --git a/src/Mod/Arch/ArchCommands.py b/src/Mod/Arch/ArchCommands.py
index 9ccfeaf1a..d70807cf5 100644
--- a/src/Mod/Arch/ArchCommands.py
+++ b/src/Mod/Arch/ArchCommands.py
@@ -423,7 +423,12 @@ def getShapeFromMesh(mesh,fast=True,tolerance=0.001,flat=False,cut=True):
pts = []
for pp in p:
pts.append(FreeCAD.Vector(pp[0],pp[1],pp[2]))
- faces.append(Part.Face(Part.makePolygon(pts)))
+ try:
+ f = Part.Face(Part.makePolygon(pts))
+ except:
+ pass
+ else:
+ faces.append(f)
shell = Part.makeShell(faces)
solid = Part.Solid(shell)
solid = solid.removeSplitter()
@@ -509,6 +514,14 @@ def meshToShape(obj,mark=True,fast=True,tol=0.001,flat=False,cut=True):
return newobj
return None
+def removeCurves(shape,tolerance=5):
+ '''removeCurves(shape,tolerance=5): replaces curved faces in a shape
+ with faceted segments'''
+ import Mesh
+ t = shape.cleaned().tessellate(tolerance)
+ m = Mesh.Mesh(t)
+ return getShapeFromMesh(m)
+
def removeShape(objs,mark=True):
'''removeShape(objs,mark=True): takes an arch object (wall or structure) built on a cubic shape, and removes
the inner shape, keeping its length, width and height as parameters. If mark is True, objects that cannot
diff --git a/src/Mod/Arch/ArchMaterial.py b/src/Mod/Arch/ArchMaterial.py
index 5dbdd6d94..bc035f7bf 100644
--- a/src/Mod/Arch/ArchMaterial.py
+++ b/src/Mod/Arch/ArchMaterial.py
@@ -46,8 +46,10 @@ def getMaterialContainer():
for obj in FreeCAD.ActiveDocument.Objects:
if obj.Name == "MaterialContainer":
return obj
- obj = FreeCAD.ActiveDocument.addObject("App::DocumentObjectGroup","MaterialContainer")
+ obj = FreeCAD.ActiveDocument.addObject("App::DocumentObjectGroupPython","MaterialContainer")
obj.Label = "Materials"
+ _ArchMaterialContainer(obj)
+ _ViewProviderArchMaterialContainer(obj.ViewObject)
return obj
@@ -66,7 +68,7 @@ def getDocumentMaterials():
class _CommandArchMaterial:
"the Arch Material command definition"
def GetResources(self):
- return {'Pixmap': 'Arch_Material',
+ return {'Pixmap': 'Arch_Material_Group',
'MenuText': QtCore.QT_TRANSLATE_NOOP("Arch_Material","Set material..."),
'Accel': "M, T",
'ToolTip': QtCore.QT_TRANSLATE_NOOP("Arch_Material","Creates or edits the material definition of a selected object.")}
@@ -90,6 +92,26 @@ class _CommandArchMaterial:
return False
+class _ArchMaterialContainer:
+ "The Material Container"
+ def __init__(self,obj):
+ self.Type = "MaterialContainer"
+ obj.Proxy = self
+
+ def execute(self,obj):
+ return
+
+
+class _ViewProviderArchMaterialContainer:
+ "A View Provider for the Material Container"
+
+ def __init__(self,vobj):
+ vobj.Proxy = self
+
+ def getIcon(self):
+ return ":/icons/Arch_Material_Group.svg"
+
+
class _ArchMaterial:
"The Material object"
def __init__(self,obj):
@@ -97,11 +119,18 @@ class _ArchMaterial:
obj.Proxy = self
def execute(self,obj):
+ if obj.Material and FreeCAD.GuiUp:
+ if "Color" in obj.Material:
+ c = tuple([float(f) for f in obj.Material['Color'].strip("()").split(",")])
+ for p in obj.InList:
+ if hasattr(p,"BaseMaterial"):
+ if p.BaseMaterial.Name == obj.Name:
+ p.ViewObject.ShapeColor = c
return
class _ViewProviderArchMaterial:
- "A View Provider for the MechanicalMaterial object"
+ "A View Provider for the Material object"
def __init__(self,vobj):
vobj.Proxy = self
@@ -158,6 +187,8 @@ class _ArchMaterialTaskPanel:
"sets the task box contents from self.material"
if 'Name' in self.material:
self.form.FieldName.setText(self.material['Name'])
+ elif self.obj:
+ self.form.FieldName.setText(self.obj.Label)
if 'Description' in self.material:
self.form.FieldDescription.setText(self.material['Description'])
if 'Color' in self.material:
@@ -168,7 +199,6 @@ class _ArchMaterialTaskPanel:
colorPix = QtGui.QPixmap(16,16)
colorPix.fill(self.color)
self.form.ButtonColor.setIcon(QtGui.QIcon(colorPix))
- self.form.FieldColor.setText(self.material['Color'])
if 'StandardCode' in self.material:
self.form.FieldCode.setText(self.material['StandardCode'])
if 'ProductURL' in self.material:
@@ -188,10 +218,7 @@ class _ArchMaterialTaskPanel:
if hasattr(self.obj,"Material"):
self.obj.Material = self.material
self.obj.Label = self.material['Name']
- FreeCADGui.Control.closeDialog()
-
- def reject(self):
- FreeCADGui.Control.closeDialog()
+ FreeCADGui.ActiveDocument.resetEdit()
def chooseMat(self, card):
"sets self.material from a card"
diff --git a/src/Mod/Arch/ArchMaterial.ui b/src/Mod/Arch/ArchMaterial.ui
index 5d75191f3..90789cfc1 100644
--- a/src/Mod/Arch/ArchMaterial.ui
+++ b/src/Mod/Arch/ArchMaterial.ui
@@ -6,7 +6,7 @@
00
- 223
+ 193233
@@ -82,13 +82,6 @@
-
-
-
- ()
-
-
-
diff --git a/src/Mod/Arch/Resources/Arch.qrc b/src/Mod/Arch/Resources/Arch.qrc
index 143d8c271..a3310217c 100644
--- a/src/Mod/Arch/Resources/Arch.qrc
+++ b/src/Mod/Arch/Resources/Arch.qrc
@@ -55,6 +55,7 @@
icons/Git.svgicons/Arch_Component.svgicons/Arch_Material.svg
+ icons/Arch_Material_Group.svgui/archprefs-base.uiui/archprefs-defaults.uiui/archprefs-import.ui
diff --git a/src/Mod/Arch/Resources/icons/Arch_Material_Group.svg b/src/Mod/Arch/Resources/icons/Arch_Material_Group.svg
new file mode 100644
index 000000000..2bab17b3a
--- /dev/null
+++ b/src/Mod/Arch/Resources/icons/Arch_Material_Group.svg
@@ -0,0 +1,680 @@
+
+
+
+
diff --git a/src/Mod/Arch/importIFC.py b/src/Mod/Arch/importIFC.py
index e827d6001..16d573e44 100644
--- a/src/Mod/Arch/importIFC.py
+++ b/src/Mod/Arch/importIFC.py
@@ -838,6 +838,15 @@ def export(exportList,filename):
isi = ifcfile.createIfcStyledItem(None,[psa],None)
isr = ifcfile.createIfcStyledRepresentation(context,"Style","Material",[isi])
imd = ifcfile.createIfcMaterialDefinitionRepresentation(None,None,[isr],mat)
+ relobjs = []
+ for o in m.InList:
+ if hasattr(o,"BaseMaterial"):
+ if o.BaseMaterial:
+ if o.BaseMaterial.Name == m.Name:
+ if o.Name in products:
+ relobjs.append(products[o.Name])
+ if relobjs:
+ ifcfile.createIfcRelAssociatesMaterial(ifcopenshell.guid.compress(uuid.uuid1().hex),history,'MaterialLink','',relobjs,mat)
if DEBUG: print "writing ",filename,"..."
ifcfile.write(filename)
@@ -989,42 +998,44 @@ def getRepresentation(ifcfile,context,obj,forcebrep=False,subtraction=False,tess
curves = True
break
if curves:
- shapetype = "triangulated"
- tris = fcsolid.tessellate(tessellation)
- for tri in tris[1]:
- pts = [ifcfile.createIfcCartesianPoint(tuple(tris[0][i])) for i in tri]
- loop = ifcfile.createIfcPolyLoop(pts)
- bound = ifcfile.createIfcFaceOuterBound(loop,True)
- face = ifcfile.createIfcFace([bound])
- faces.append(face)
- else:
- shapetype = "brep"
- for fcface in fcsolid.Faces:
- loops = []
- verts = [v.Point for v in Part.Wire(DraftGeomUtils.sortEdges(fcface.OuterWire.Edges)).Vertexes]
- c = fcface.CenterOfMass
- v1 = verts[0].sub(c)
- v2 = verts[1].sub(c)
- n = fcface.normalAt(0,0)
- if DraftVecUtils.angle(v2,v1,n) >= 0:
- verts.reverse() # inverting verts order if the direction is couterclockwise
- pts = [ifcfile.createIfcCartesianPoint(tuple(v)) for v in verts]
- loop = ifcfile.createIfcPolyLoop(pts)
- bound = ifcfile.createIfcFaceOuterBound(loop,True)
- loops.append(bound)
- for wire in fcface.Wires:
- if wire.hashCode() != fcface.OuterWire.hashCode():
- verts = [v.Point for v in Part.Wire(DraftGeomUtils.sortEdges(wire.Edges)).Vertexes]
- v1 = verts[0].sub(c)
- v2 = verts[1].sub(c)
- if DraftVecUtils.angle(v2,v1,DraftVecUtils.neg(n)) >= 0:
- verts.reverse()
- pts = [ifcfile.createIfcCartesianPoint(tuple(v)) for v in verts]
- loop = ifcfile.createIfcPolyLoop(pts)
- bound = ifcfile.createIfcFaceBound(loop,True)
- loops.append(bound)
- face = ifcfile.createIfcFace(loops)
- faces.append(face)
+ #shapetype = "triangulated"
+ #tris = fcsolid.tessellate(tessellation)
+ #for tri in tris[1]:
+ # pts = [ifcfile.createIfcCartesianPoint(tuple(tris[0][i])) for i in tri]
+ # loop = ifcfile.createIfcPolyLoop(pts)
+ # bound = ifcfile.createIfcFaceOuterBound(loop,True)
+ # face = ifcfile.createIfcFace([bound])
+ # faces.append(face)
+ fcsolid = Arch.removeCurves(fcsolid)
+
+ shapetype = "brep"
+ for fcface in fcsolid.Faces:
+ loops = []
+ verts = [v.Point for v in Part.Wire(DraftGeomUtils.sortEdges(fcface.OuterWire.Edges)).Vertexes]
+ c = fcface.CenterOfMass
+ v1 = verts[0].sub(c)
+ v2 = verts[1].sub(c)
+ n = fcface.normalAt(0,0)
+ if DraftVecUtils.angle(v2,v1,n) >= 0:
+ verts.reverse() # inverting verts order if the direction is couterclockwise
+ pts = [ifcfile.createIfcCartesianPoint(tuple(v)) for v in verts]
+ loop = ifcfile.createIfcPolyLoop(pts)
+ bound = ifcfile.createIfcFaceOuterBound(loop,True)
+ loops.append(bound)
+ for wire in fcface.Wires:
+ if wire.hashCode() != fcface.OuterWire.hashCode():
+ verts = [v.Point for v in Part.Wire(DraftGeomUtils.sortEdges(wire.Edges)).Vertexes]
+ v1 = verts[0].sub(c)
+ v2 = verts[1].sub(c)
+ if DraftVecUtils.angle(v2,v1,DraftVecUtils.neg(n)) >= 0:
+ verts.reverse()
+ pts = [ifcfile.createIfcCartesianPoint(tuple(v)) for v in verts]
+ loop = ifcfile.createIfcPolyLoop(pts)
+ bound = ifcfile.createIfcFaceBound(loop,True)
+ loops.append(bound)
+ face = ifcfile.createIfcFace(loops)
+ faces.append(face)
+
shell = ifcfile.createIfcClosedShell(faces)
shape = ifcfile.createIfcFacetedBrep(shell)
shapes.append(shape)
@@ -1033,6 +1044,14 @@ def getRepresentation(ifcfile,context,obj,forcebrep=False,subtraction=False,tess
# set surface style
if FreeCAD.GuiUp and (not subtraction) and hasattr(obj.ViewObject,"ShapeColor"):
+ # only set a surface style if the object has no material.
+ # apparently not needed, no harm in having both.
+ #m = False
+ #if hasattr(obj,"BaseMaterial"):
+ # if obj.BaseMaterial:
+ # if "Color" in obj.BaseMaterial.Material:
+ # m = True
+ #if not m:
rgb = obj.ViewObject.ShapeColor[:3]
if rgb in surfstyles:
psa = surfstyles[rgb]
diff --git a/src/Mod/Material/materials-editor.ui b/src/Mod/Material/materials-editor.ui
index d8fb395f1..4c26adac7 100644
--- a/src/Mod/Material/materials-editor.ui
+++ b/src/Mod/Material/materials-editor.ui
@@ -7,7 +7,7 @@
00450
- 599
+ 604
@@ -545,7 +545,7 @@
Execution Instructions
- Specific execution or installation insstructions
+ Specific execution or installation instructionsItemIsSelectable|ItemIsEditable|ItemIsDragEnabled|ItemIsUserCheckable|ItemIsEnabled
@@ -879,10 +879,10 @@
- Section Fill Pattern
+ View Linewidth
- An SVG pattern to apply on cut faces, expressed as either a name of an existing pattern (such as "simple") or a complete <pattern>...</pattern> SVG element
+ An optional linewidth factor for viewed faces
@@ -893,10 +893,18 @@
- View Linewidth
+ Section Color
- An optional linewidth factor for viewed faces
+ A base color for sectionned faces, expressed with 3 comma-separated float values, for ex. 0.5,0.5,0.5
+
+
+
+
+ Section Fill Pattern
+
+
+ An SVG pattern to apply on cut faces, expressed as either a name of an existing pattern (such as "simple") or a complete <pattern>...</pattern> SVG element