Merge branch 'master' of ssh://git.code.sf.net/p/free-cad/code
This commit is contained in:
commit
d8dba90ab4
|
@ -649,11 +649,15 @@ def getExtrusionData(obj,scale=1):
|
||||||
return None
|
return None
|
||||||
if hasattr(obj,"Proxy"):
|
if hasattr(obj,"Proxy"):
|
||||||
if hasattr(obj.Proxy,"BaseProfile") and hasattr(obj.Proxy,"ExtrusionVector"):
|
if hasattr(obj.Proxy,"BaseProfile") and hasattr(obj.Proxy,"ExtrusionVector"):
|
||||||
|
import Part
|
||||||
pl = FreeCAD.Placement(obj.Placement)
|
pl = FreeCAD.Placement(obj.Placement)
|
||||||
r = FreeCAD.Rotation(obj.Placement.Rotation)
|
r = FreeCAD.Rotation(obj.Placement.Rotation)
|
||||||
if pl.isNull():
|
if pl.isNull():
|
||||||
pl = r = None
|
pl = r = None
|
||||||
return getTuples(obj.Proxy.BaseProfile,scale,pl), getTuples(obj.Proxy.ExtrusionVector,scale,r)
|
if len(obj.Proxy.BaseProfile.Edges) == 1:
|
||||||
|
if isinstance(obj.Proxy.BaseProfile.Edges[0].Curve,Part.Circle):
|
||||||
|
return "circle", getTuples(obj.Proxy.BaseProfile.Edges[0].Curve.Center,scale), obj.Proxy.BaseProfile.Edges[0].Curve.Radius*scale, getTuples(obj.Proxy.ExtrusionVector,scale,r)
|
||||||
|
return "polyline", getTuples(obj.Proxy.BaseProfile,scale,pl), getTuples(obj.Proxy.ExtrusionVector,scale,r)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def getBrepFacesData(obj,scale=1):
|
def getBrepFacesData(obj,scale=1):
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -279,6 +279,26 @@
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_10">
|
||||||
|
<item>
|
||||||
|
<widget class="Gui::PrefCheckBox" name="checkBox_3">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string><html><head/><body><p>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.</p></body></html></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>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|
|
@ -385,6 +385,18 @@ class IfcDocument(object):
|
||||||
f.write(l)
|
f.write(l)
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
|
def union(self,solids):
|
||||||
|
"""union(solids): creates a boolean union between all the solids of the list"""
|
||||||
|
if len(solids) == 1:
|
||||||
|
return solids[0]
|
||||||
|
else:
|
||||||
|
s1 = solids.pop(0)
|
||||||
|
s2 = solids.pop(0)
|
||||||
|
base = create(self._fileobject,"IfcBooleanResult",["UNION",s1,s2])
|
||||||
|
for s in solids:
|
||||||
|
base = create(self._fileobject,"IfcBooleanResult",["UNION",base,s])
|
||||||
|
return base
|
||||||
|
|
||||||
def addPlacement(self,reference=None,origin=(0,0,0),xaxis=(1,0,0),zaxis=(0,0,1),local=True):
|
def addPlacement(self,reference=None,origin=(0,0,0),xaxis=(1,0,0),zaxis=(0,0,1),local=True):
|
||||||
"""addPlacement([reference,origin,xaxis,zaxis,local]): adds a placement. origin,
|
"""addPlacement([reference,origin,xaxis,zaxis,local]): adds a placement. origin,
|
||||||
xaxis and zaxis can be either tuples or 3d vectors. If local is False, a global
|
xaxis and zaxis can be either tuples or 3d vectors. If local is False, a global
|
||||||
|
@ -463,14 +475,14 @@ class IfcDocument(object):
|
||||||
self._relate(storey,wal)
|
self._relate(storey,wal)
|
||||||
return wal
|
return wal
|
||||||
|
|
||||||
def addStructure(self,ifctype,shapes,storey=None,placement=None,name="Default Structure",description=None,standard=False):
|
def addStructure(self,ifctype,shapes,storey=None,placement=None,name="Default Structure",description=None,extrusion=False):
|
||||||
"""addStructure(ifctype,shapes,[storey,placement,name,description]): creates a structure
|
"""addStructure(ifctype,shapes,[storey,placement,name,description]): creates a structure
|
||||||
from the given representation shape(s). Ifctype is the type of structural object (IfcBeam, IfcColumn, etc)"""
|
from the given representation shape(s). Ifctype is the type of structural object (IfcBeam, IfcColumn, etc)"""
|
||||||
if not placement:
|
if not placement:
|
||||||
placement = self.addPlacement()
|
placement = self.addPlacement()
|
||||||
if not isinstance(shapes,list):
|
if not isinstance(shapes,list):
|
||||||
shapes = [shapes]
|
shapes = [shapes]
|
||||||
if standard:
|
if extrusion:
|
||||||
solidType = "SweptSolid"
|
solidType = "SweptSolid"
|
||||||
else:
|
else:
|
||||||
solidType = "Brep"
|
solidType = "Brep"
|
||||||
|
@ -508,17 +520,23 @@ class IfcDocument(object):
|
||||||
"""addPolyline(points): creates a polyline from the given points"""
|
"""addPolyline(points): creates a polyline from the given points"""
|
||||||
pts = [create(self._fileobject,"IfcCartesianPoint",getTuple(p)) for p in points]
|
pts = [create(self._fileobject,"IfcCartesianPoint",getTuple(p)) for p in points]
|
||||||
pol = create(self._fileobject,"IfcPolyline",[pts])
|
pol = create(self._fileobject,"IfcPolyline",[pts])
|
||||||
return pol
|
area = create(self._fileobject,"IfcArbitraryClosedProfileDef",["AREA",None,pol])
|
||||||
|
return area
|
||||||
|
|
||||||
def addExtrusion(self,polyline,extrusion,placement=None):
|
def addCircle(self,radius):
|
||||||
"""addExtrusion(polyline,extrusion,[placement]): makes an
|
"""addCircle(radius): creates a polyline from the given points"""
|
||||||
|
lpl = self.addPlacement()
|
||||||
|
cir = create(self._fileobject,"IfcCircleProfileDef",["AREA",None,lpl,float(radius)])
|
||||||
|
return cir
|
||||||
|
|
||||||
|
def addExtrusion(self,profile,extrusion,placement=None):
|
||||||
|
"""addExtrusion(profile,extrusion,[placement]): makes an
|
||||||
extrusion of the given polyline with the given extrusion vector"""
|
extrusion of the given polyline with the given extrusion vector"""
|
||||||
if not placement:
|
if not placement:
|
||||||
placement = self.addPlacement(local=False)
|
placement = self.addPlacement(local=False)
|
||||||
value,norm = getValueAndDirection(extrusion)
|
value,norm = getValueAndDirection(extrusion)
|
||||||
edir = create(self._fileobject,"IfcDirection",[norm])
|
edir = create(self._fileobject,"IfcDirection",[norm])
|
||||||
area = create(self._fileobject,"IfcArbitraryClosedProfileDef",["AREA",None,polyline])
|
solid = create(self._fileobject,"IfcExtrudedAreaSolid",[profile,placement,edir,value])
|
||||||
solid = create(self._fileobject,"IfcExtrudedAreaSolid",[area,placement,edir,value])
|
|
||||||
return solid
|
return solid
|
||||||
|
|
||||||
def addExtrudedPolyline(self,points,extrusion,placement=None):
|
def addExtrudedPolyline(self,points,extrusion,placement=None):
|
||||||
|
@ -528,6 +546,15 @@ class IfcDocument(object):
|
||||||
exp = self.addExtrusion(pol,extrusion,placement)
|
exp = self.addExtrusion(pol,extrusion,placement)
|
||||||
return exp
|
return exp
|
||||||
|
|
||||||
|
def addExtrudedCircle(self,center,radius,extrusion,placement=None):
|
||||||
|
"""addExtrudedCircle(radius,extrusion,[placement]): makes an extruded circle
|
||||||
|
from the given radius and the given extrusion vector"""
|
||||||
|
cir = self.addCircle(radius)
|
||||||
|
if not placement:
|
||||||
|
placement = self.addPlacement(origin=center)
|
||||||
|
exp = self.addExtrusion(cir,extrusion,placement)
|
||||||
|
return exp
|
||||||
|
|
||||||
def addFace(self,face):
|
def addFace(self,face):
|
||||||
"""addFace(face): creates a face from the given face data (a list of lists of points).
|
"""addFace(face): creates a face from the given face data (a list of lists of points).
|
||||||
The first is the outer wire, the next are optional inner wires. They must be reversed in order"""
|
The first is the outer wire, the next are optional inner wires. They must be reversed in order"""
|
||||||
|
|
|
@ -34,6 +34,7 @@ SCHEMA = "http://www.steptools.com/support/stdev_docs/express/ifc2x3/ifc2x3_tc1.
|
||||||
MAKETEMPFILES = False # if True, shapes are passed from ifcopenshell to freecad through temp files
|
MAKETEMPFILES = False # if True, shapes are passed from ifcopenshell to freecad through temp files
|
||||||
DEBUG = True # this is only for the python console, this value is overridden when importing through the GUI
|
DEBUG = True # this is only for the python console, this value is overridden when importing through the GUI
|
||||||
SKIP = ["IfcBuildingElementProxy","IfcFlowTerminal","IfcFurnishingElement"] # default. overwritten by the GUI options
|
SKIP = ["IfcBuildingElementProxy","IfcFlowTerminal","IfcFurnishingElement"] # default. overwritten by the GUI options
|
||||||
|
TOUCH = True # arch objects based on profiles need to be reexecuted after loading the file (this is temporary)
|
||||||
# end config
|
# end config
|
||||||
|
|
||||||
if open.__module__ == '__builtin__':
|
if open.__module__ == '__builtin__':
|
||||||
|
@ -62,7 +63,7 @@ def insert(filename,docname,skip=None):
|
||||||
|
|
||||||
def getConfig():
|
def getConfig():
|
||||||
"Gets Arch IFC import preferences"
|
"Gets Arch IFC import preferences"
|
||||||
global CREATE_IFC_GROUPS, ASMESH, PREFIX_NUMBERS, FORCE_PYTHON_PARSER, SEPARATE_OPENINGS, SEPARATE_PLACEMENTS
|
global CREATE_IFC_GROUPS, ASMESH, PREFIX_NUMBERS, FORCE_PYTHON_PARSER, SEPARATE_OPENINGS, SEPARATE_PLACEMENTS, JOINSOLIDS
|
||||||
CREATE_IFC_GROUPS = False
|
CREATE_IFC_GROUPS = False
|
||||||
IMPORT_IFC_FURNITURE = False
|
IMPORT_IFC_FURNITURE = False
|
||||||
ASMESH = ["IfcFurnishingElement"]
|
ASMESH = ["IfcFurnishingElement"]
|
||||||
|
@ -76,6 +77,7 @@ def getConfig():
|
||||||
SEPARATE_OPENINGS = p.GetBool("ifcSeparateOpenings",False)
|
SEPARATE_OPENINGS = p.GetBool("ifcSeparateOpenings",False)
|
||||||
SEPARATE_PLACEMENTS = p.GetBool("ifcSeparatePlacements",False)
|
SEPARATE_PLACEMENTS = p.GetBool("ifcSeparatePlacements",False)
|
||||||
PREFIX_NUMBERS = p.GetBool("ifcPrefixNumbers",False)
|
PREFIX_NUMBERS = p.GetBool("ifcPrefixNumbers",False)
|
||||||
|
JOINSOLIDS = p.GetBool("ifcJoinSolids",False)
|
||||||
skiplist = p.GetString("ifcSkip","")
|
skiplist = p.GetString("ifcSkip","")
|
||||||
if skiplist:
|
if skiplist:
|
||||||
SKIP = skiplist.split(",")
|
SKIP = skiplist.split(",")
|
||||||
|
@ -923,9 +925,9 @@ def export(exportList,filename):
|
||||||
version of IfcOpenShell available from https://github.com/aothms/IfcOpenShell"""
|
version of IfcOpenShell available from https://github.com/aothms/IfcOpenShell"""
|
||||||
return
|
return
|
||||||
import ifcWriter
|
import ifcWriter
|
||||||
|
import Arch,Draft
|
||||||
|
|
||||||
# creating base IFC project
|
# creating base IFC project
|
||||||
import Arch,Draft
|
|
||||||
getConfig()
|
getConfig()
|
||||||
ifcWriter.PRECISION = Draft.precision()
|
ifcWriter.PRECISION = Draft.precision()
|
||||||
p = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Arch")
|
p = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Arch")
|
||||||
|
@ -944,6 +946,13 @@ def export(exportList,filename):
|
||||||
# get all children and reorder list to get buildings and floors processed first
|
# get all children and reorder list to get buildings and floors processed first
|
||||||
objectslist = Draft.getGroupContents(exportList,walls=True,addgroups=True)
|
objectslist = Draft.getGroupContents(exportList,walls=True,addgroups=True)
|
||||||
objectslist = Arch.pruneIncluded(objectslist)
|
objectslist = Arch.pruneIncluded(objectslist)
|
||||||
|
|
||||||
|
# workaround: loaded objects loose their profile info - needs to recompute...
|
||||||
|
if TOUCH:
|
||||||
|
for o in objectslist:
|
||||||
|
if Draft.getType(o) in ["Wall", "Structure"]:
|
||||||
|
o.Proxy.execute(o)
|
||||||
|
|
||||||
buildings = []
|
buildings = []
|
||||||
floors = []
|
floors = []
|
||||||
others = []
|
others = []
|
||||||
|
@ -971,20 +980,45 @@ def export(exportList,filename):
|
||||||
|
|
||||||
if DEBUG: print "adding ",obj.Label
|
if DEBUG: print "adding ",obj.Label
|
||||||
|
|
||||||
|
# getting geometry
|
||||||
if not forcebrep:
|
if not forcebrep:
|
||||||
gdata = Arch.getExtrusionData(obj,scaling)
|
gdata = Arch.getExtrusionData(obj,scaling)
|
||||||
#if DEBUG: print "extrusion data for ",obj.Label," : ",gdata
|
#if DEBUG: print "extrusion data for ",obj.Label," : ",gdata
|
||||||
if not gdata:
|
if not gdata:
|
||||||
fdata = Arch.getBrepFacesData(obj,scaling)
|
fdata = Arch.getBrepFacesData(obj,scaling)
|
||||||
#if DEBUG: print "brep data for ",obj.Label," : ",fdata
|
#if DEBUG: print "brep data for ",obj.Label," : ",fdata
|
||||||
if DEBUG: print " Brep"
|
|
||||||
if not fdata:
|
if not fdata:
|
||||||
if obj.isDerivedFrom("Part::Feature"):
|
if obj.isDerivedFrom("Part::Feature"):
|
||||||
print "IFC export: error retrieving the shape of object ", obj.Name
|
print "IFC export: error retrieving the shape of object ", obj.Name
|
||||||
continue
|
continue
|
||||||
|
else:
|
||||||
|
if DEBUG: print " No geometry"
|
||||||
|
else:
|
||||||
|
if DEBUG: print " Brep"
|
||||||
else:
|
else:
|
||||||
if DEBUG: print " Extrusion"
|
if DEBUG: print " Extrusion"
|
||||||
|
|
||||||
|
# compute final placement
|
||||||
|
basepoint = None
|
||||||
|
if obj.isDerivedFrom("Part::Feature"):
|
||||||
|
b1 = None
|
||||||
|
b2 = None
|
||||||
|
if hasattr(obj,"Base"):
|
||||||
|
if obj.Base:
|
||||||
|
b1 = FreeCAD.Vector(obj.Base.Placement.Base).multiply(scaling)
|
||||||
|
if hasattr(obj,"Placement"):
|
||||||
|
b2 = FreeCAD.Vector(obj.Placement.Base).multiply(scaling)
|
||||||
|
if b2:
|
||||||
|
if b1:
|
||||||
|
basepoint = b2.add(b1)
|
||||||
|
else:
|
||||||
|
basepoint = b2
|
||||||
|
elif b1:
|
||||||
|
basepoint = b1
|
||||||
|
if basepoint:
|
||||||
|
basepoint = Arch.getTuples(basepoint)
|
||||||
|
|
||||||
|
# writing text log
|
||||||
spacer = ""
|
spacer = ""
|
||||||
for i in range(36-len(obj.Label)):
|
for i in range(36-len(obj.Label)):
|
||||||
spacer += " "
|
spacer += " "
|
||||||
|
@ -997,6 +1031,7 @@ def export(exportList,filename):
|
||||||
tp = otype
|
tp = otype
|
||||||
txt.append(obj.Label + spacer + tp)
|
txt.append(obj.Label + spacer + tp)
|
||||||
|
|
||||||
|
# writing IFC data
|
||||||
if otype == "Building":
|
if otype == "Building":
|
||||||
ifc.addBuilding( name=name )
|
ifc.addBuilding( name=name )
|
||||||
|
|
||||||
|
@ -1009,11 +1044,18 @@ def export(exportList,filename):
|
||||||
if parent:
|
if parent:
|
||||||
parent = ifc.findByName("IfcBuildingStorey",str(parent.Label))
|
parent = ifc.findByName("IfcBuildingStorey",str(parent.Label))
|
||||||
if gdata:
|
if gdata:
|
||||||
ifc.addWall( ifc.addExtrudedPolyline(gdata[0],gdata[1]), storey=parent, name=name, standard=True )
|
if gdata[0] == "polyline":
|
||||||
|
ifc.addWall( ifc.addExtrudedPolyline(gdata[1], gdata[2]), storey=parent, name=name, standard=True )
|
||||||
|
elif gdata[0] == "circle":
|
||||||
|
ifc.addWall( ifc.addExtrudedCircle(gdata[1], gdata[2], gdata[3]), storey=parent, name=name )
|
||||||
elif fdata:
|
elif fdata:
|
||||||
|
if JOINSOLIDS:
|
||||||
|
ifc.addWall( ifc.join([ifc.addFacetedBrep(f) for f in fdata]), storey=parent, name=name )
|
||||||
|
else:
|
||||||
ifc.addWall( [ifc.addFacetedBrep(f) for f in fdata], storey=parent, name=name )
|
ifc.addWall( [ifc.addFacetedBrep(f) for f in fdata], storey=parent, name=name )
|
||||||
|
|
||||||
elif otype == "Structure":
|
elif otype == "Structure":
|
||||||
|
placement = None
|
||||||
if parent:
|
if parent:
|
||||||
parent = ifc.findByName("IfcBuildingStorey",str(parent.Label))
|
parent = ifc.findByName("IfcBuildingStorey",str(parent.Label))
|
||||||
role = "IfcBeam"
|
role = "IfcBeam"
|
||||||
|
@ -1025,14 +1067,28 @@ def export(exportList,filename):
|
||||||
elif obj.Role == "Foundation":
|
elif obj.Role == "Foundation":
|
||||||
role = "IfcFooting"
|
role = "IfcFooting"
|
||||||
if gdata:
|
if gdata:
|
||||||
|
if gdata[0] == "polyline":
|
||||||
#ifc.addStructure( role, ifc.addExtrudedPolyline(gdata[0],gdata[1]), storey=parent, name=name )
|
#ifc.addStructure( role, ifc.addExtrudedPolyline(gdata[0],gdata[1]), storey=parent, name=name )
|
||||||
if FreeCAD.Vector(gdata[1]).getAngle(FreeCAD.Vector(0,0,1)) < .01:
|
if FreeCAD.Vector(gdata[2]).getAngle(FreeCAD.Vector(0,0,1)) < .01:
|
||||||
# Workaround for non-Z extrusions, apparently not supported by ifc++ TODO: fix this
|
# the placement of polylines is weird... The Z values from the polyline info is not used,
|
||||||
ifc.addStructure( role, ifc.addExtrudedPolyline(gdata[0],gdata[1]), storey=parent, name=name, standard=True )
|
# so we need to give it now as a placement.
|
||||||
|
if basepoint:
|
||||||
|
if round(basepoint[2],Draft.precision()) != 0:
|
||||||
|
placement = ifc.addPlacement(origin=(0.0,0.0,basepoint[2]))
|
||||||
|
ifc.addStructure( role, ifc.addExtrudedPolyline(gdata[1],gdata[2]), storey=parent, placement=placement, name=name, extrusion=True )
|
||||||
else:
|
else:
|
||||||
|
# Workaround for non-Z extrusions, apparently not supported by ifc++ TODO: fix this
|
||||||
|
print " switching to Brep"
|
||||||
fdata = Arch.getBrepFacesData(obj,scaling)
|
fdata = Arch.getBrepFacesData(obj,scaling)
|
||||||
ifc.addStructure( role, [ifc.addFacetedBrep(f) for f in fdata], storey=parent, name=name )
|
ifc.addStructure( role, [ifc.addFacetedBrep(f) for f in fdata], storey=parent, name=name )
|
||||||
|
elif gdata[0] == "circle":
|
||||||
|
if basepoint:
|
||||||
|
placement = ifc.addPlacement(origin=basepoint)
|
||||||
|
ifc.addStructure( role, ifc.addExtrudedCircle(gdata[1], gdata[2], gdata[3]), storey=parent, placement=placement, name=name, extrusion=True )
|
||||||
elif fdata:
|
elif fdata:
|
||||||
|
if JOINSOLIDS:
|
||||||
|
ifc.addStructure( role, ifc.join([ifc.addFacetedBrep(f) for f in fdata]), storey=parent, name=name )
|
||||||
|
else:
|
||||||
ifc.addStructure( role, [ifc.addFacetedBrep(f) for f in fdata], storey=parent, name=name )
|
ifc.addStructure( role, [ifc.addFacetedBrep(f) for f in fdata], storey=parent, name=name )
|
||||||
|
|
||||||
elif otype == "Window":
|
elif otype == "Window":
|
||||||
|
@ -1052,8 +1108,12 @@ def export(exportList,filename):
|
||||||
if obj.Role == "Door":
|
if obj.Role == "Door":
|
||||||
role = "IfcDoor"
|
role = "IfcDoor"
|
||||||
if gdata:
|
if gdata:
|
||||||
ifc.addWindow( role, obj.Width*scaling, obj.Height*scaling, ifc.addExtrudedPolyline(gdata[0],gdata[1]), host=parent, name=name )
|
if gdata[0] == "polyline":
|
||||||
|
ifc.addWindow( role, obj.Width*scaling, obj.Height*scaling, ifc.addExtrudedPolyline(gdata[1], gdata[2]), host=parent, name=name )
|
||||||
elif fdata:
|
elif fdata:
|
||||||
|
if JOINSOLIDS:
|
||||||
|
ifc.addWindow( role, obj.Width*scaling, obj.Height*scaling, ifc.union([ifc.addFacetedBrep(f) for f in fdata]), host=parent, name=name )
|
||||||
|
else:
|
||||||
ifc.addWindow( role, obj.Width*scaling, obj.Height*scaling, [ifc.addFacetedBrep(f) for f in fdata], host=parent, name=name )
|
ifc.addWindow( role, obj.Width*scaling, obj.Height*scaling, [ifc.addFacetedBrep(f) for f in fdata], host=parent, name=name )
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
@ -1082,6 +1142,8 @@ def export(exportList,filename):
|
||||||
f.write(txtstring)
|
f.write(txtstring)
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
|
FreeCAD.ActiveDocument.recompute()
|
||||||
|
|
||||||
|
|
||||||
def explore(filename=None):
|
def explore(filename=None):
|
||||||
"explore the contents of an ifc file in a Qt dialog"
|
"explore the contents of an ifc file in a Qt dialog"
|
||||||
|
|
|
@ -4174,11 +4174,13 @@ class _Shape2DView(_DraftObject):
|
||||||
obj.addProperty("App::PropertyEnumeration","ProjectionMode","Draft","The way the viewed object must be projected")
|
obj.addProperty("App::PropertyEnumeration","ProjectionMode","Draft","The way the viewed object must be projected")
|
||||||
obj.addProperty("App::PropertyIntegerList","FaceNumbers","Draft","The indices of the faces to be projected in Individual Faces mode")
|
obj.addProperty("App::PropertyIntegerList","FaceNumbers","Draft","The indices of the faces to be projected in Individual Faces mode")
|
||||||
obj.addProperty("App::PropertyBool","HiddenLines","Draft","Show hidden lines")
|
obj.addProperty("App::PropertyBool","HiddenLines","Draft","Show hidden lines")
|
||||||
obj.addProperty("App::PropertyBool","Tessellation","Draft","Tessellate BSplines into line segments using number of spline poles")
|
obj.addProperty("App::PropertyBool","Tessellation","Draft","Tessellate Ellipses and BSplines into line segments")
|
||||||
|
obj.addProperty("App::PropertyFloat","SegmentLength","Draft","Length of line segments if tessellating Ellipses or BSplines into line segments")
|
||||||
obj.Projection = Vector(0,0,1)
|
obj.Projection = Vector(0,0,1)
|
||||||
obj.ProjectionMode = ["Solid","Individual Faces","Cutlines","Cutfaces"]
|
obj.ProjectionMode = ["Solid","Individual Faces","Cutlines","Cutfaces"]
|
||||||
obj.HiddenLines = False
|
obj.HiddenLines = False
|
||||||
obj.Tessellation = True
|
obj.Tessellation = False
|
||||||
|
obj.SegmentLength = .05
|
||||||
_DraftObject.__init__(self,obj,"Shape2DView")
|
_DraftObject.__init__(self,obj,"Shape2DView")
|
||||||
|
|
||||||
def getProjected(self,obj,shape,direction):
|
def getProjected(self,obj,shape,direction):
|
||||||
|
@ -4195,9 +4197,10 @@ class _Shape2DView(_DraftObject):
|
||||||
edges.append(g)
|
edges.append(g)
|
||||||
#return Part.makeCompound(edges)
|
#return Part.makeCompound(edges)
|
||||||
if hasattr(obj,"Tessellation"):
|
if hasattr(obj,"Tessellation"):
|
||||||
return DraftGeomUtils.cleanProjection(Part.makeCompound(edges),obj.Tessellation)
|
return DraftGeomUtils.cleanProjection(Part.makeCompound(edges),obj.Tessellation,obj.SegmentLength)
|
||||||
else:
|
else:
|
||||||
return DraftGeomUtils.cleanProjection(Part.makeCompound(edges))
|
return Part.makeCompound(edges)
|
||||||
|
#return DraftGeomUtils.cleanProjection(Part.makeCompound(edges))
|
||||||
|
|
||||||
def execute(self,obj):
|
def execute(self,obj):
|
||||||
import DraftGeomUtils
|
import DraftGeomUtils
|
||||||
|
|
|
@ -1808,10 +1808,12 @@ def curvetowire(obj,steps):
|
||||||
p0 = p
|
p0 = p
|
||||||
return edgelist
|
return edgelist
|
||||||
|
|
||||||
def cleanProjection(shape,tessellate=False):
|
def cleanProjection(shape,tessellate=True,seglength=.05):
|
||||||
"returns a valid compound of edges, by recreating them"
|
"returns a valid compound of edges, by recreating them"
|
||||||
# this is because the projection algorithm somehow creates wrong shapes.
|
# this is because the projection algorithm somehow creates wrong shapes.
|
||||||
# they dispay fine, but on loading the file the shape is invalid
|
# they dispay fine, but on loading the file the shape is invalid
|
||||||
|
# Now with tanderson's fix to ProjectionAlgos, that isn't the case, but this
|
||||||
|
# can be used for tessellating ellipses and splines for DXF output-DF
|
||||||
oldedges = shape.Edges
|
oldedges = shape.Edges
|
||||||
newedges = []
|
newedges = []
|
||||||
for e in oldedges:
|
for e in oldedges:
|
||||||
|
@ -1826,6 +1828,9 @@ def cleanProjection(shape,tessellate=False):
|
||||||
else:
|
else:
|
||||||
newedges.append(e.Curve.toShape())
|
newedges.append(e.Curve.toShape())
|
||||||
elif geomType(e) == "Ellipse":
|
elif geomType(e) == "Ellipse":
|
||||||
|
if tessellate:
|
||||||
|
newedges.append(Part.Wire(curvetowire(e, seglength)))
|
||||||
|
else:
|
||||||
if len(e.Vertexes) > 1:
|
if len(e.Vertexes) > 1:
|
||||||
a = Part.Arc(e.Curve,e.FirstParameter,e.LastParameter).toShape()
|
a = Part.Arc(e.Curve,e.FirstParameter,e.LastParameter).toShape()
|
||||||
newedges.append(a)
|
newedges.append(a)
|
||||||
|
@ -1834,7 +1839,7 @@ def cleanProjection(shape,tessellate=False):
|
||||||
elif geomType(e) == "BSplineCurve" or \
|
elif geomType(e) == "BSplineCurve" or \
|
||||||
geomType(e) == "BezierCurve":
|
geomType(e) == "BezierCurve":
|
||||||
if tessellate:
|
if tessellate:
|
||||||
newedges.append(Part.Wire(curvetowire(e,e.Curve.NbPoles)))
|
newedges.append(Part.Wire(curvetowire(e,seglength)))
|
||||||
else:
|
else:
|
||||||
if isLine(e.Curve):
|
if isLine(e.Curve):
|
||||||
l = Part.Line(e.Vertexes[0].Point,e.Vertexes[-1].Point).toShape()
|
l = Part.Line(e.Vertexes[0].Point,e.Vertexes[-1].Point).toShape()
|
||||||
|
@ -1847,6 +1852,36 @@ def cleanProjection(shape,tessellate=False):
|
||||||
print "Debug: error cleaning edge ",e
|
print "Debug: error cleaning edge ",e
|
||||||
return Part.makeCompound(newedges)
|
return Part.makeCompound(newedges)
|
||||||
|
|
||||||
|
def curvetosegment(curve,seglen):
|
||||||
|
points = curve.discretize(seglen)
|
||||||
|
p0 = points[0]
|
||||||
|
edgelist = []
|
||||||
|
for p in points[1:]:
|
||||||
|
edge = Part.makeLine((p0.x,p0.y,p0.z),(p.x,p.y,p.z))
|
||||||
|
edgelist.append(edge)
|
||||||
|
p0 = p
|
||||||
|
return edgelist
|
||||||
|
|
||||||
|
def tessellateProjection(shape,seglen):
|
||||||
|
''' Returns projection with BSplines and Ellipses broken into line segments.
|
||||||
|
Useful for exporting projected views to *dxf files.'''
|
||||||
|
oldedges = shape.Edges
|
||||||
|
newedges = []
|
||||||
|
for e in oldedges:
|
||||||
|
try:
|
||||||
|
if geomType(e) == "Line":
|
||||||
|
newedges.append(e.Curve.toShape())
|
||||||
|
elif geomType(e) == "Circle":
|
||||||
|
newedges.append(e.Curve.toShape())
|
||||||
|
elif geomType(e) == "Ellipse":
|
||||||
|
newedges.append(Part.Wire(curvetosegment(e,seglen)))
|
||||||
|
elif geomType(e) == "BSplineCurve":
|
||||||
|
newedges.append(Part.Wire(curvetosegment(e,seglen)))
|
||||||
|
else:
|
||||||
|
newedges.append(e)
|
||||||
|
except:
|
||||||
|
print "Debug: error cleaning edge ",e
|
||||||
|
return Part.makeCompound(newedges)
|
||||||
|
|
||||||
# circle functions *********************************************************
|
# circle functions *********************************************************
|
||||||
|
|
||||||
|
|
|
@ -60,7 +60,7 @@
|
||||||
#include <TColgp_Array1OfPnt2d.hxx>
|
#include <TColgp_Array1OfPnt2d.hxx>
|
||||||
#include <BRep_Tool.hxx>
|
#include <BRep_Tool.hxx>
|
||||||
#include <BRepMesh.hxx>
|
#include <BRepMesh.hxx>
|
||||||
|
#include <BRepLib.hxx>
|
||||||
#include <BRepAdaptor_CompCurve.hxx>
|
#include <BRepAdaptor_CompCurve.hxx>
|
||||||
#include <Handle_BRepAdaptor_HCompCurve.hxx>
|
#include <Handle_BRepAdaptor_HCompCurve.hxx>
|
||||||
#include <Approx_Curve3d.hxx>
|
#include <Approx_Curve3d.hxx>
|
||||||
|
@ -122,6 +122,18 @@ TopoDS_Shape ProjectionAlgos::invertY(const TopoDS_Shape& shape)
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
//added by tanderson. aka blobfish.
|
||||||
|
//projection algorithms build a 2d curve(pcurve) but no 3d curve.
|
||||||
|
//this causes problems with meshing algorithms after save and load.
|
||||||
|
static const TopoDS_Shape& build3dCurves(const TopoDS_Shape &shape)
|
||||||
|
{
|
||||||
|
TopExp_Explorer it;
|
||||||
|
for (it.Init(shape, TopAbs_EDGE); it.More(); it.Next())
|
||||||
|
BRepLib::BuildCurve3d(TopoDS::Edge(it.Current()));
|
||||||
|
return shape;
|
||||||
|
}
|
||||||
|
|
||||||
void ProjectionAlgos::execute(void)
|
void ProjectionAlgos::execute(void)
|
||||||
{
|
{
|
||||||
Handle( HLRBRep_Algo ) brep_hlr = new HLRBRep_Algo;
|
Handle( HLRBRep_Algo ) brep_hlr = new HLRBRep_Algo;
|
||||||
|
@ -141,17 +153,16 @@ void ProjectionAlgos::execute(void)
|
||||||
// extracting the result sets:
|
// extracting the result sets:
|
||||||
HLRBRep_HLRToShape shapes( brep_hlr );
|
HLRBRep_HLRToShape shapes( brep_hlr );
|
||||||
|
|
||||||
V = shapes.VCompound ();// hard edge visibly
|
V = build3dCurves(shapes.VCompound ());// hard edge visibly
|
||||||
V1 = shapes.Rg1LineVCompound();// Smoth edges visibly
|
V1 = build3dCurves(shapes.Rg1LineVCompound());// Smoth edges visibly
|
||||||
VN = shapes.RgNLineVCompound();// contour edges visibly
|
VN = build3dCurves(shapes.RgNLineVCompound());// contour edges visibly
|
||||||
VO = shapes.OutLineVCompound();// contours apparents visibly
|
VO = build3dCurves(shapes.OutLineVCompound());// contours apparents visibly
|
||||||
VI = shapes.IsoLineVCompound();// isoparamtriques visibly
|
VI = build3dCurves(shapes.IsoLineVCompound());// isoparamtriques visibly
|
||||||
H = shapes.HCompound ();// hard edge invisibly
|
H = build3dCurves(shapes.HCompound ());// hard edge invisibly
|
||||||
H1 = shapes.Rg1LineHCompound();// Smoth edges invisibly
|
H1 = build3dCurves(shapes.Rg1LineHCompound());// Smoth edges invisibly
|
||||||
HN = shapes.RgNLineHCompound();// contour edges invisibly
|
HN = build3dCurves(shapes.RgNLineHCompound());// contour edges invisibly
|
||||||
HO = shapes.OutLineHCompound();// contours apparents invisibly
|
HO = build3dCurves(shapes.OutLineHCompound());// contours apparents invisibly
|
||||||
HI = shapes.IsoLineHCompound();// isoparamtriques invisibly
|
HI = build3dCurves(shapes.IsoLineHCompound());// isoparamtriques invisibly
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ProjectionAlgos::getSVG(ExtractionType type, double scale, double tolerance, double hiddenscale)
|
std::string ProjectionAlgos::getSVG(ExtractionType type, double scale, double tolerance, double hiddenscale)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user