Skip to content

Commit

Permalink
Arch: Misc fixes
Browse files Browse the repository at this point in the history
* Allow to export subtractions as separate elements in IFC
* Fixed Survey tool
* Removed unused Arch preferences
  • Loading branch information
yorikvanhavre committed Jun 7, 2014
1 parent 39bda90 commit 92a565f
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 74 deletions.
98 changes: 58 additions & 40 deletions src/Mod/Arch/ArchCommands.py
@@ -1,3 +1,5 @@
# -*- coding: utf8 -*-

#***************************************************************************
#* *
#* Copyright (c) 2011 *
Expand Down Expand Up @@ -633,17 +635,16 @@ def getTuples(data,scale=1,placement=None,normal=None,close=True):
print "Arch.getTuples(): Wrong profile data"
return t

def getIfcExtrusionData(obj,scale=1):
"""getIfcExtrusionData(obj,[scale]): returns a closed path (a list of tuples), a tuple expressing an extrusion
def getIfcExtrusionData(obj,scale=1,nosubs=False):
"""getIfcExtrusionData(obj,[scale,nosubs]): returns a closed path (a list of tuples), a tuple expressing an extrusion
vector, and a list of 3 tuples for base position, x axis and z axis. Or returns None, if a base loop and
an extrusion direction cannot be extracted. Scale can indicate a scale factor."""
if hasattr(obj,"Additions"):
if obj.Additions:
# provisorily treat objs with additions as breps
# TODO provisorily treat objs with additions as breps
return None
if hasattr(obj,"Subtractions"):
if hasattr(obj,"Subtractions") and not nosubs:
if obj.Subtractions:
# provisorily treat objs with subtractions as breps
return None
if hasattr(obj,"Proxy"):
if hasattr(obj.Proxy,"getProfiles"):
Expand Down Expand Up @@ -725,42 +726,50 @@ def getIfcExtrusionData(obj,scale=1):
return "polyline", getTuples(p,scale), getTuples(v,scale), d
return None

def getIfcBrepFacesData(obj,scale=1,tessellation=1):
def getIfcBrepFacesData(obj,scale=1,sub=False,tessellation=1):
"""getIfcBrepFacesData(obj,[scale,tesselation]): returns a list(0) of lists(1) of lists(2) of lists(3),
list(3) being a list of vertices defining a loop, list(2) describing a face from one or
more loops, list(1) being the whole solid made of several faces, list(0) being the list
of solids inside the object. Scale can indicate a scaling factor. Tesselation is the tesselation
factor to apply on curved faces."""
if hasattr(obj,"Shape"):
shape = None
if sub:
if hasattr(obj,"Proxy"):
if hasattr(obj.Proxy,"getSubVolume"):
shape = obj.Proxy.getSubVolume(obj)
if not shape:
if hasattr(obj,"Shape"):
if obj.Shape:
if not obj.Shape.isNull():
if obj.Shape.isValid():
shape = obj.Shape
if shape:
import Part
if obj.Shape:
if not obj.Shape.isNull():
if obj.Shape.isValid():
sols = []
for sol in obj.Shape.Solids:
s = []
curves = False
for face in sol.Faces:
for e in face.Edges:
if not isinstance(e.Curve,Part.Line):
curves = True
if curves:
tris = sol.tessellate(tessellation)
for tri in tris[1]:
f = []
for i in tri:
f.append(getTuples(tris[0][i],scale))
s.append([f])
else:
for face in sol.Faces:
f = []
f.append(getTuples(face.OuterWire,scale,normal=face.normalAt(0,0),close=False))
for wire in face.Wires:
if wire.hashCode() != face.OuterWire.hashCode():
f.append(getTuples(wire,scale,normal=DraftVecUtils.neg(face.normalAt(0,0)),close=False))
s.append(f)
sols.append(s)
return sols
sols = []
for sol in shape.Solids:
s = []
curves = False
for face in sol.Faces:
for e in face.Edges:
if not isinstance(e.Curve,Part.Line):
curves = True
if curves:
tris = sol.tessellate(tessellation)
for tri in tris[1]:
f = []
for i in tri:
f.append(getTuples(tris[0][i],scale))
s.append([f])
else:
for face in sol.Faces:
f = []
f.append(getTuples(face.OuterWire,scale,normal=face.normalAt(0,0),close=False))
for wire in face.Wires:
if wire.hashCode() != face.OuterWire.hashCode():
f.append(getTuples(wire,scale,normal=DraftVecUtils.neg(face.normalAt(0,0)),close=False))
s.append(f)
sols.append(s)
return sols
return None

def getHost(obj,strict=True):
Expand Down Expand Up @@ -864,19 +873,24 @@ def survey(callback=False):
if not o.HasSubObjects:
# entire object
anno = FreeCAD.ActiveDocument.addObject("App::AnnotationLabel","surveyLabel")
anno.BasePosition = o.Object.Shape.CenterOfMass
if hasattr(o.Object.Shape,"CenterOfMass"):
anno.BasePosition = o.Object.Shape.CenterOfMass
else:
anno.BasePosition = o.Object.Shape.BoundBox.Center
FreeCAD.SurveyObserver.labels.append(anno.Name)
t = ""
if o.Object.Shape.Solids:
t = FreeCAD.Units.Quantity(o.Object.Shape.Volume,FreeCAD.Units.Volume)
t = t.getUserPreferred()[0]
t = t.replace("^3","³")
anno.LabelText = "v " + t
FreeCAD.Console.PrintMessage("Object: " + n + ", Element: Whole, Volume: " + t + "\n")
FreeCAD.Console.PrintMessage("Object: " + n + ", Element: Whole, Volume: " + t.decode("utf8") + "\n")
elif o.Object.Shape.Faces:
t = FreeCAD.Units.Quantity(o.Object.Shape.Area,FreeCAD.Units.Area)
t = t.getUserPreferred()[0]
t = t.replace("^2","²")
anno.LabelText = "a " + t
FreeCAD.Console.PrintMessage("Object: " + n + ", Element: Whole, Area: " + t + "\n")
FreeCAD.Console.PrintMessage("Object: " + n + ", Element: Whole, Area: " + t.decode("utf8") + "\n")
else:
t = FreeCAD.Units.Quantity(o.Object.Shape.Length,FreeCAD.Units.Length)
t = t.getUserPreferred()[0]
Expand All @@ -892,14 +906,18 @@ def survey(callback=False):
if "Vertex" in el:
anno.BasePosition = e.Point
else:
anno.BasePosition = e.CenterOfMass
if hasattr(e,"CenterOfMass"):
anno.BasePosition = e.CenterOfMass
else:
anno.BasePosition = e.BoundBox.Center
FreeCAD.SurveyObserver.labels.append(anno.Name)
t = ""
if "Face" in el:
t = FreeCAD.Units.Quantity(e.Area,FreeCAD.Units.Area)
t = t.getUserPreferred()[0]
t = t.replace("^2","²")
anno.LabelText = "a " + t
FreeCAD.Console.PrintMessage("Object: " + n + ", Element: " + el + ", Area: "+ t + "\n")
FreeCAD.Console.PrintMessage("Object: " + n + ", Element: " + el + ", Area: "+ t.decode("utf8") + "\n")
elif "Edge" in el:
t = FreeCAD.Units.Quantity(e.Length,FreeCAD.Units.Length)
t = t.getUserPreferred()[0]
Expand Down
6 changes: 3 additions & 3 deletions src/Mod/Arch/Arch_rc.py

Large diffs are not rendered by default.

20 changes: 0 additions & 20 deletions src/Mod/Arch/Resources/ui/archprefs-import.ui
Expand Up @@ -279,26 +279,6 @@
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_10">
<item>
<widget class="Gui::PrefCheckBox" name="checkBox_3">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Objects containing multiple solids are normally exported as multiple representations. Some applications don't like that,though. You can use this option to unite these solids into one.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Join multi-solid objects</string>
</property>
<property name="prefEntry" stdset="0">
<cstring>ifcJoinSolids</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Arch</cstring>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
Expand Down
5 changes: 4 additions & 1 deletion src/Mod/Arch/ifcWriter.py
Expand Up @@ -459,7 +459,10 @@ def _relate(self,container,entities):
rel = create(self._fileobject,"IfcRelContainedInSpatialStructure",[uid(),self._owner,'StoreyLink','',entities,container])
self._storeyRelations[sid] = rel
else:
create(self._fileobject,"IfcRelAggregates",[uid(),self._owner,'Relationship','',container,entities])
if entities[0].is_a("IfcOpeningElement"):
create(self._fileobject,"IfcRelVoidsElement",[uid(),self._owner,'Opening','',container,entities[0]])
else:
create(self._fileobject,"IfcRelAggregates",[uid(),self._owner,'Relationship','',container,entities])

def addProduct(self,elttype,shapes,storey=None,placement=None,name="Unnamed element",description=None,extra=None):
"""addProduct(elttype,representations,[storey,placement,name,description,extra]): creates an element of the given type
Expand Down
25 changes: 15 additions & 10 deletions src/Mod/Arch/importIFC.py
Expand Up @@ -73,12 +73,8 @@ def insert(filename,docname,skip=None):
def getConfig():
"Gets Arch IFC import preferences"
global SKIP, CREATE_IFC_GROUPS, ASMESH, PREFIX_NUMBERS, FORCE_PYTHON_PARSER, SEPARATE_OPENINGS, SEPARATE_PLACEMENTS, JOINSOLIDS, AGGREGATE_WINDOWS
CREATE_IFC_GROUPS = False
IMPORT_IFC_FURNITURE = False
ASMESH = ["IfcFurnishingElement"]
PREFIX_NUMBERS = False
FORCE_PYTHON_PARSER = False
SEPARATE_OPENINGS = False
p = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Arch")
CREATE_IFC_GROUPS = p.GetBool("createIfcGroups",False)
FORCE_PYTHON_PARSER = p.GetBool("forceIfcPythonParser",False)
Expand Down Expand Up @@ -1009,7 +1005,9 @@ def export(exportList,filename):
if parent:
parent = ifc.findByName("IfcBuilding",str(parent.Label))

if otype == "Building":
if otype == "Site":
pass # TODO manage sites
elif otype == "Building":
ifc.addBuilding( name=name )
elif otype == "Floor":
ifc.addStorey( building=parent, name=name )
Expand All @@ -1028,7 +1026,7 @@ def export(exportList,filename):

# get representation
if not forcebrep:
gdata = Arch.getIfcExtrusionData(obj,scaling)
gdata = Arch.getIfcExtrusionData(obj,scaling,SEPARATE_OPENINGS)
#if DEBUG: print " extrusion data for ",obj.Label," : ",gdata
if not gdata:
fdata = Arch.getIfcBrepFacesData(obj,scaling)
Expand Down Expand Up @@ -1057,10 +1055,7 @@ def export(exportList,filename):
else:
print "debug: unknow extrusion type"
elif fdata:
if JOINSOLIDS:
representation = ifc.join([ifc.addFacetedBrep(f, color=color) for f in fdata])
else:
representation = [ifc.addFacetedBrep(f, color=color) for f in fdata]
representation = [ifc.addFacetedBrep(f, color=color) for f in fdata]

# create ifc object
ifctype = "Ifc" + ifctype
Expand All @@ -1080,7 +1075,17 @@ def export(exportList,filename):
ifctype = "IfcBuildingElementProxy"
extra = ["ELEMENT"]
p = ifc.addProduct( ifctype, representation, storey=parent, placement=placement, name=name, description=descr, extra=extra )

if p:

# removing openings
if SEPARATE_OPENINGS and gdata:
for o in obj.Subtractions:
print "Subtracting ",o.Label
fdata = Arch.getIfcBrepFacesData(o,scaling,sub=True)
representation = [ifc.addFacetedBrep(f, color=color) for f in fdata]
p2 = ifc.addProduct( "IfcOpeningElement", representation, storey=p, placement=None, name=str(o.Label), description=None)

# writing text log
spacer = ""
for i in range(36-len(obj.Label)):
Expand Down

0 comments on commit 92a565f

Please sign in to comment.