Merge branch 'master' of ssh://git.code.sf.net/p/free-cad/code
This commit is contained in:
commit
86a69f830e
|
@ -455,7 +455,6 @@ else(FREECAD_LIBPACK_USE)
|
|||
TKXDESTEP
|
||||
TKXDEIGES
|
||||
TKMeshVS
|
||||
TKAdvTools
|
||||
)
|
||||
set(OCC_INCLUDE_DIR ${OCE_INCLUDE_DIRS})
|
||||
set(OCC_FOUND ${OCE_FOUND})
|
||||
|
|
|
@ -89,7 +89,6 @@ IF(OCC_LIBRARY)
|
|||
TKXDESTEP
|
||||
TKXDEIGES
|
||||
TKMeshVS
|
||||
TKAdvTools
|
||||
)
|
||||
ENDIF(OCC_LIBRARY)
|
||||
|
||||
|
|
2
src/3rdParty/salomesmesh/Makefile.am
vendored
2
src/3rdParty/salomesmesh/Makefile.am
vendored
|
@ -21,7 +21,7 @@ endif
|
|||
#AM_LDFLAGS = -version-info 1:0:0 -Wl,--no-undefined -L$(OCC_LIB)
|
||||
AM_LDFLAGS = -version-info 1:0:0 -L$(OCC_LIB) \
|
||||
-lTKernel -lTKService -lTKMath -lTKBRep -lTKTopAlgo -lTKGeomAlgo \
|
||||
-lTKGeomBase -lTKG3d -lTKG2d -lTKMeshVS -lTKShHealing -lTKPrim -lTKAdvTools
|
||||
-lTKGeomBase -lTKG3d -lTKG2d -lTKMeshVS -lTKShHealing -lTKPrim
|
||||
|
||||
#uninstall-local:
|
||||
# -rm -rf $(DESTDIR)$(libdir)
|
||||
|
|
|
@ -26,12 +26,17 @@
|
|||
#ifndef SMESH_IndexedMapOfShape_HeaderFile
|
||||
#define SMESH_IndexedMapOfShape_HeaderFile
|
||||
|
||||
#include "Standard_Version.hxx"
|
||||
#include "SMESH_SMESH.hxx"
|
||||
|
||||
#include "SMESHDS_DataMapOfShape.hxx"
|
||||
|
||||
#ifndef __BORLANDC__
|
||||
#if OCC_VERSION_HEX >= 0x060703
|
||||
#include <NCollection_IndexedMap.hxx>
|
||||
#else
|
||||
#include <NCollection_DefineIndexedMap.hxx>
|
||||
#endif
|
||||
#else
|
||||
#include <SMESH_DefineIndexedMap.hxx>
|
||||
#endif
|
||||
|
@ -40,27 +45,42 @@
|
|||
|
||||
/// Class SMESH_IndexedMapOfShape
|
||||
|
||||
DEFINE_BASECOLLECTION (SMESH_BaseCollectionShape, TopoDS_Shape)
|
||||
|
||||
#if OCC_VERSION_HEX >= 0x060703
|
||||
#ifndef __BORLANDC__
|
||||
DEFINE_INDEXEDMAP (SMESH_IndexedMapOfShape, SMESH_BaseCollectionShape, TopoDS_Shape)
|
||||
typedef NCollection_IndexedMap<TopoDS_Shape> SMESH_IndexedMapOfShape;
|
||||
#else
|
||||
DEFINE_BASECOLLECTION (SMESH_BaseCollectionShape, TopoDS_Shape)
|
||||
SMESH_DEFINE_INDEXEDMAP (SMESH_IndexedMapOfShape, SMESH_BaseCollectionShape, TopoDS_Shape)
|
||||
#endif
|
||||
#else
|
||||
DEFINE_INDEXEDMAP (SMESH_IndexedMapOfShape, SMESH_BaseCollectionShape, TopoDS_Shape)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef SMESH_IndexedDataMapOfShapeIndexedMapOfShape_HeaderFile
|
||||
#define SMESH_IndexedDataMapOfShapeIndexedMapOfShape_HeaderFile
|
||||
|
||||
#if OCC_VERSION_HEX >= 0x060703
|
||||
#include <NCollection_IndexedDataMap.hxx>
|
||||
#else
|
||||
#include <NCollection_DefineIndexedDataMap.hxx>
|
||||
#endif
|
||||
|
||||
/// Class SMESH_IndexedDataMapOfShapeIndexedMapOfShape
|
||||
|
||||
|
||||
#if OCC_VERSION_HEX >= 0x060703
|
||||
typedef NCollection_IndexedDataMap<SMESH_IndexedMapOfShape,TopoDS_Shape> SMESH_IndexedDataMapOfShapeIndexedMapOfShape;
|
||||
#else
|
||||
#include <NCollection_DefineIndexedDataMap.hxx>
|
||||
/// Class SMESH_IndexedDataMapOfShapeIndexedMapOfShape
|
||||
DEFINE_BASECOLLECTION (SMESH_BaseCollectionIndexedMapOfShape, SMESH_IndexedMapOfShape)
|
||||
DEFINE_INDEXEDDATAMAP (SMESH_IndexedDataMapOfShapeIndexedMapOfShape,
|
||||
SMESH_BaseCollectionIndexedMapOfShape, TopoDS_Shape,
|
||||
SMESH_IndexedMapOfShape)
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
#ifndef SMESH_MeshEditor_HeaderFile
|
||||
#define SMESH_MeshEditor_HeaderFile
|
||||
|
||||
#include "Standard_Version.hxx"
|
||||
|
||||
#include "SMESH_SMESH.hxx"
|
||||
|
||||
#include "SMDS_MeshElement.hxx"
|
||||
|
|
|
@ -28,13 +28,21 @@
|
|||
|
||||
#include "SMESH_SMESH.hxx"
|
||||
|
||||
#if OCC_VERSION_HEX >= 0x060703
|
||||
#include <NCollection_Sequence.hxx>
|
||||
#else
|
||||
#include <NCollection_DefineSequence.hxx>
|
||||
#endif
|
||||
|
||||
#include <SMDS_MeshElement.hxx>
|
||||
|
||||
typedef const SMDS_MeshElement* SMDS_MeshElementPtr;
|
||||
|
||||
#if OCC_VERSION_HEX >= 0x060703
|
||||
typedef NCollection_Sequence<SMDS_MeshElementPtr> SMESH_SequenceOfElemPtr;
|
||||
#else
|
||||
DEFINE_BASECOLLECTION (SMESH_BaseCollectionElemPtr, SMDS_MeshElementPtr)
|
||||
DEFINE_SEQUENCE (SMESH_SequenceOfElemPtr, SMESH_BaseCollectionElemPtr, SMDS_MeshElementPtr)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -29,12 +29,19 @@
|
|||
#include "SMESH_SMESH.hxx"
|
||||
|
||||
#include <NCollection_DefineSequence.hxx>
|
||||
#if OCC_VERSION_HEX >= 0x060703
|
||||
#include <NCollection_IncAllocator.hxx>
|
||||
#include <NCollection_Sequence.hxx>
|
||||
#endif
|
||||
|
||||
typedef const SMDS_MeshNode* SMDS_MeshNodePtr;
|
||||
|
||||
#if OCC_VERSION_HEX >= 0x060703
|
||||
typedef NCollection_Sequence<SMDS_MeshNodePtr> SMESH_SequenceOfNode;
|
||||
#else
|
||||
DEFINE_BASECOLLECTION (SMESH_BaseCollectionNodePtr, SMDS_MeshNodePtr)
|
||||
DEFINE_SEQUENCE(SMESH_SequenceOfNode,
|
||||
SMESH_BaseCollectionNodePtr, SMDS_MeshNodePtr)
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -66,12 +66,17 @@
|
|||
#ifndef StdMeshers_Array2OfNode_HeaderFile
|
||||
#define StdMeshers_Array2OfNode_HeaderFile
|
||||
typedef const SMDS_MeshNode* SMDS_MeshNodePtr;
|
||||
DEFINE_BASECOLLECTION (StdMeshers_BaseCollectionNodePtr, SMDS_MeshNodePtr)
|
||||
|
||||
#ifndef __BORLANDC__
|
||||
DEFINE_ARRAY2(StdMeshers_Array2OfNode,
|
||||
StdMeshers_BaseCollectionNodePtr, SMDS_MeshNodePtr)
|
||||
#if OCC_VERSION_HEX >= 0x060703
|
||||
typedef NCollection_Array2<SMDS_MeshNodePtr> StdMeshers_Array2OfNode;
|
||||
#else
|
||||
DEFINE_BASECOLLECTION (StdMeshers_BaseCollectionNodePtr, SMDS_MeshNodePtr)
|
||||
DEFINE_ARRAY2(StdMeshers_Array2OfNode,
|
||||
StdMeshers_BaseCollectionNodePtr, SMDS_MeshNodePtr)
|
||||
#endif
|
||||
#else
|
||||
DEFINE_BASECOLLECTION (StdMeshers_BaseCollectionNodePtr, SMDS_MeshNodePtr)
|
||||
SMESH_DEFINE_ARRAY2(StdMeshers_Array2OfNode,
|
||||
StdMeshers_BaseCollectionNodePtr, SMDS_MeshNodePtr)
|
||||
#endif
|
||||
|
|
|
@ -37,8 +37,6 @@ __title__="FreeCAD Arch Commands"
|
|||
__author__ = "Yorik van Havre"
|
||||
__url__ = "http://www.freecadweb.org"
|
||||
|
||||
CURVEMODE = "PARAMETER" # For trimmed curves. CARTESIAN or PARAMETER
|
||||
|
||||
# module functions ###############################################
|
||||
|
||||
def getStringList(objects):
|
||||
|
@ -597,191 +595,6 @@ def check(objectslist,includehidden=False):
|
|||
bad.append([o,translate("Arch","contains faces that are not part of any solid")])
|
||||
return bad
|
||||
|
||||
def getTuples(data,scale=1,placement=None,normal=None,close=True):
|
||||
"""getTuples(data,[scale,placement,normal,close]): returns a tuple or a list of tuples from a vector
|
||||
or from the vertices of a shape. Scale can indicate a scale factor"""
|
||||
rnd = False
|
||||
import Part
|
||||
if isinstance(data,FreeCAD.Vector):
|
||||
if placement:
|
||||
data = placement.multVec(data)
|
||||
if rnd:
|
||||
data = DraftVecUtils.rounded(data)
|
||||
return (data.x*scale,data.y*scale,data.z*scale)
|
||||
elif isinstance(data,Part.Shape):
|
||||
t = []
|
||||
if len(data.Wires) == 1:
|
||||
import Part,DraftGeomUtils
|
||||
data = Part.Wire(DraftGeomUtils.sortEdges(data.Wires[0].Edges))
|
||||
verts = data.Vertexes
|
||||
try:
|
||||
c = data.CenterOfMass
|
||||
v1 = verts[0].Point.sub(c)
|
||||
v2 = verts[1].Point.sub(c)
|
||||
if DraftVecUtils.angle(v2,v1,normal) >= 0:
|
||||
# inverting verts order if the direction is couterclockwise
|
||||
verts.reverse()
|
||||
except:
|
||||
pass
|
||||
for v in verts:
|
||||
pt = v.Point
|
||||
if placement:
|
||||
if not placement.isNull():
|
||||
pt = placement.multVec(pt)
|
||||
if rnd:
|
||||
pt = DraftVecUtils.rounded(pt)
|
||||
t.append((pt.x*scale,pt.y*scale,pt.z*scale))
|
||||
|
||||
if close: # faceloops must not be closed, but ifc profiles must.
|
||||
t.append(t[0])
|
||||
else:
|
||||
print "Arch.getTuples(): Wrong profile data"
|
||||
return t
|
||||
|
||||
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:
|
||||
# TODO provisorily treat objs with additions as breps
|
||||
return None
|
||||
if hasattr(obj,"Subtractions") and not nosubs:
|
||||
if obj.Subtractions:
|
||||
return None
|
||||
if hasattr(obj,"Proxy"):
|
||||
if hasattr(obj.Proxy,"getProfiles"):
|
||||
p = obj.Proxy.getProfiles(obj,noplacement=True)
|
||||
v = obj.Proxy.getExtrusionVector(obj,noplacement=True)
|
||||
if (len(p) == 1) and v:
|
||||
p = p[0]
|
||||
r = FreeCAD.Placement()
|
||||
#b = p.CenterOfMass
|
||||
r = obj.Proxy.getPlacement(obj)
|
||||
#b = obj.Placement.multVec(FreeCAD.Vector())
|
||||
#r.Rotation = DraftVecUtils.getRotation(v,FreeCAD.Vector(0,0,1))
|
||||
d = [r.Base,DraftVecUtils.rounded(r.Rotation.multVec(FreeCAD.Vector(1,0,0))),DraftVecUtils.rounded(r.Rotation.multVec(FreeCAD.Vector(0,0,1)))]
|
||||
#r = r.inverse()
|
||||
#print "getExtrusionData: computed placement:",r
|
||||
import Part
|
||||
if len(p.Edges) == 1:
|
||||
if isinstance(p.Edges[0].Curve,Part.Circle):
|
||||
# Circle profile
|
||||
r1 = p.Edges[0].Curve.Radius*scale
|
||||
return "circle", [getTuples(p.Edges[0].Curve.Center,scale), r1], getTuples(v,scale), d
|
||||
elif isinstance(p.Edges[0].Curve,Part.Ellipse):
|
||||
# Ellipse profile
|
||||
r1 = p.Edges[0].Curve.MajorRadius*scale
|
||||
r2 = p.Edges[0].Curve.MinorRadius*scale
|
||||
return "ellipse", [getTuples(p.Edges[0].Curve.Center,scale), r1, r2], getTuples(v,scale), d
|
||||
curves = False
|
||||
for e in p.Edges:
|
||||
if isinstance(e.Curve,Part.Circle):
|
||||
curves = True
|
||||
elif not isinstance(e.Curve,Part.Line):
|
||||
print "Arch.getIfcExtrusionData: Warning: unsupported edge type in profile"
|
||||
if curves:
|
||||
# Composite profile
|
||||
ecurves = []
|
||||
last = None
|
||||
import DraftGeomUtils
|
||||
edges = DraftGeomUtils.sortEdges(p.Edges)
|
||||
for e in edges:
|
||||
if isinstance(e.Curve,Part.Circle):
|
||||
import math
|
||||
follow = True
|
||||
if last:
|
||||
if not DraftVecUtils.equals(last,e.Vertexes[0].Point):
|
||||
follow = False
|
||||
last = e.Vertexes[0].Point
|
||||
else:
|
||||
last = e.Vertexes[-1].Point
|
||||
else:
|
||||
last = e.Vertexes[-1].Point
|
||||
p1 = math.degrees(-DraftVecUtils.angle(e.Vertexes[0].Point.sub(e.Curve.Center)))
|
||||
p2 = math.degrees(-DraftVecUtils.angle(e.Vertexes[-1].Point.sub(e.Curve.Center)))
|
||||
da = DraftVecUtils.angle(e.valueAt(e.FirstParameter+0.1).sub(e.Curve.Center),e.Vertexes[0].Point.sub(e.Curve.Center))
|
||||
if p1 < 0:
|
||||
p1 = 360 + p1
|
||||
if p2 < 0:
|
||||
p2 = 360 + p2
|
||||
if da > 0:
|
||||
follow = not(follow)
|
||||
if CURVEMODE == "CARTESIAN":
|
||||
# BUGGY
|
||||
p1 = getTuples(e.Vertexes[0].Point,scale)
|
||||
p2 = getTuples(e.Vertexes[-1].Point,scale)
|
||||
ecurves.append(["arc",getTuples(e.Curve.Center,scale),e.Curve.Radius*scale,[p1,p2],follow,CURVEMODE])
|
||||
else:
|
||||
verts = [vertex.Point for vertex in e.Vertexes]
|
||||
if last:
|
||||
if not DraftVecUtils.equals(last,verts[0]):
|
||||
verts.reverse()
|
||||
last = e.Vertexes[0].Point
|
||||
else:
|
||||
last = e.Vertexes[-1].Point
|
||||
else:
|
||||
last = e.Vertexes[-1].Point
|
||||
ecurves.append(["line",[getTuples(vert,scale) for vert in verts]])
|
||||
return "composite", ecurves, getTuples(v,scale), d
|
||||
else:
|
||||
# Polyline profile
|
||||
return "polyline", getTuples(p,scale), getTuples(v,scale), d
|
||||
return None
|
||||
|
||||
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."""
|
||||
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
|
||||
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 getIfcElevation(obj):
|
||||
"""getIfcElevation(obj): Returns the lowest height (Z coordinate) of this object"""
|
||||
if obj.isDerivedFrom("Part::Feature"):
|
||||
b = obj.Shape.BoundBox
|
||||
return b.ZMin
|
||||
return 0
|
||||
|
||||
def getHost(obj,strict=True):
|
||||
"""getHost(obj,[strict]): returns the host of the current object. If strict is true (default),
|
||||
the host can only be an object of a higher level than the given one, or in other words, if a wall
|
||||
|
|
|
@ -34,7 +34,7 @@ else:
|
|||
def translate(ctxt,txt):
|
||||
return txt
|
||||
|
||||
def makeSpace(objects=None,name=translate("Arch","Space")):
|
||||
def makeSpace(objects=None,baseobj=None,name=translate("Arch","Space")):
|
||||
"""makeSpace([objects]): Creates a space object from the given objects. Objects can be one
|
||||
document object, in which case it becomes the base shape of the space object, or a list of
|
||||
selection objects as got from getSelectionEx(), or a list of tuples (object, subobjectname)"""
|
||||
|
@ -42,6 +42,8 @@ def makeSpace(objects=None,name=translate("Arch","Space")):
|
|||
_Space(obj)
|
||||
if FreeCAD.GuiUp:
|
||||
_ViewProviderSpace(obj.ViewObject)
|
||||
if baseobj:
|
||||
objects = baseobj
|
||||
if objects:
|
||||
if not isinstance(objects,list):
|
||||
objects = [objects]
|
||||
|
|
|
@ -1048,10 +1048,10 @@ def export(exportList,filename):
|
|||
|
||||
# get representation
|
||||
if (not forcebrep) and (not brepflag):
|
||||
gdata = Arch.getIfcExtrusionData(obj,scaling,SEPARATE_OPENINGS)
|
||||
gdata = getIfcExtrusionData(obj,scaling,SEPARATE_OPENINGS)
|
||||
#if DEBUG: print " extrusion data for ",obj.Label," : ",gdata
|
||||
if not gdata:
|
||||
fdata = Arch.getIfcBrepFacesData(obj,scaling)
|
||||
fdata = getIfcBrepFacesData(obj,scaling)
|
||||
#if DEBUG: print " brep data for ",obj.Label," : ",fdata
|
||||
if not fdata:
|
||||
if obj.isDerivedFrom("Part::Feature"):
|
||||
|
@ -1094,7 +1094,7 @@ def export(exportList,filename):
|
|||
elif otype == "Window":
|
||||
extra = [obj.Width.Value*scaling, obj.Height.Value*scaling]
|
||||
elif otype == "Space":
|
||||
extra = ["ELEMENT","INTERNAL",Arch.getIfcElevation(obj)]
|
||||
extra = ["ELEMENT","INTERNAL",getIfcElevation(obj)]
|
||||
elif otype == "Part":
|
||||
extra = ["ELEMENT"]
|
||||
if not ifctype in supportedIfcTypes:
|
||||
|
@ -1109,7 +1109,7 @@ def export(exportList,filename):
|
|||
if SEPARATE_OPENINGS and gdata:
|
||||
for o in obj.Subtractions:
|
||||
print "Subtracting ",o.Label
|
||||
fdata = Arch.getIfcBrepFacesData(o,scaling,sub=True)
|
||||
fdata = getIfcBrepFacesData(o,scaling,sub=True)
|
||||
representation = [ifc.addFacetedBrep(f, color=color) for f in fdata]
|
||||
p2 = ifc.addProduct( "IfcOpeningElement", representation, storey=product, placement=None, name=str(o.Label), description=None)
|
||||
|
||||
|
@ -1172,6 +1172,195 @@ def export(exportList,filename):
|
|||
print " " + o.Label
|
||||
|
||||
|
||||
def getTuples(data,scale=1,placement=None,normal=None,close=True):
|
||||
"""getTuples(data,[scale,placement,normal,close]): returns a tuple or a list of tuples from a vector
|
||||
or from the vertices of a shape. Scale can indicate a scale factor"""
|
||||
rnd = False
|
||||
import Part
|
||||
if isinstance(data,FreeCAD.Vector):
|
||||
if placement:
|
||||
data = placement.multVec(data)
|
||||
if rnd:
|
||||
data = DraftVecUtils.rounded(data)
|
||||
return (data.x*scale,data.y*scale,data.z*scale)
|
||||
elif isinstance(data,Part.Shape):
|
||||
t = []
|
||||
if len(data.Wires) == 1:
|
||||
import Part,DraftGeomUtils
|
||||
data = Part.Wire(DraftGeomUtils.sortEdges(data.Wires[0].Edges))
|
||||
verts = data.Vertexes
|
||||
try:
|
||||
c = data.CenterOfMass
|
||||
v1 = verts[0].Point.sub(c)
|
||||
v2 = verts[1].Point.sub(c)
|
||||
if DraftVecUtils.angle(v2,v1,normal) >= 0:
|
||||
# inverting verts order if the direction is couterclockwise
|
||||
verts.reverse()
|
||||
except:
|
||||
pass
|
||||
for v in verts:
|
||||
pt = v.Point
|
||||
if placement:
|
||||
if not placement.isNull():
|
||||
pt = placement.multVec(pt)
|
||||
if rnd:
|
||||
pt = DraftVecUtils.rounded(pt)
|
||||
t.append((pt.x*scale,pt.y*scale,pt.z*scale))
|
||||
|
||||
if close: # faceloops must not be closed, but ifc profiles must.
|
||||
t.append(t[0])
|
||||
else:
|
||||
print "Arch.getTuples(): Wrong profile data"
|
||||
return t
|
||||
|
||||
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."""
|
||||
|
||||
CURVEMODE = "PARAMETER" # For trimmed curves. CARTESIAN or PARAMETER
|
||||
|
||||
if hasattr(obj,"Additions"):
|
||||
if obj.Additions:
|
||||
# TODO provisorily treat objs with additions as breps
|
||||
return None
|
||||
if hasattr(obj,"Subtractions") and not nosubs:
|
||||
if obj.Subtractions:
|
||||
return None
|
||||
if hasattr(obj,"Proxy"):
|
||||
if hasattr(obj.Proxy,"getProfiles"):
|
||||
p = obj.Proxy.getProfiles(obj,noplacement=True)
|
||||
v = obj.Proxy.getExtrusionVector(obj,noplacement=True)
|
||||
if (len(p) == 1) and v:
|
||||
p = p[0]
|
||||
r = FreeCAD.Placement()
|
||||
#b = p.CenterOfMass
|
||||
r = obj.Proxy.getPlacement(obj)
|
||||
#b = obj.Placement.multVec(FreeCAD.Vector())
|
||||
#r.Rotation = DraftVecUtils.getRotation(v,FreeCAD.Vector(0,0,1))
|
||||
d = [r.Base,DraftVecUtils.rounded(r.Rotation.multVec(FreeCAD.Vector(1,0,0))),DraftVecUtils.rounded(r.Rotation.multVec(FreeCAD.Vector(0,0,1)))]
|
||||
#r = r.inverse()
|
||||
#print "getExtrusionData: computed placement:",r
|
||||
import Part
|
||||
if len(p.Edges) == 1:
|
||||
if isinstance(p.Edges[0].Curve,Part.Circle):
|
||||
# Circle profile
|
||||
r1 = p.Edges[0].Curve.Radius*scale
|
||||
return "circle", [getTuples(p.Edges[0].Curve.Center,scale), r1], getTuples(v,scale), d
|
||||
elif isinstance(p.Edges[0].Curve,Part.Ellipse):
|
||||
# Ellipse profile
|
||||
r1 = p.Edges[0].Curve.MajorRadius*scale
|
||||
r2 = p.Edges[0].Curve.MinorRadius*scale
|
||||
return "ellipse", [getTuples(p.Edges[0].Curve.Center,scale), r1, r2], getTuples(v,scale), d
|
||||
curves = False
|
||||
for e in p.Edges:
|
||||
if isinstance(e.Curve,Part.Circle):
|
||||
curves = True
|
||||
elif not isinstance(e.Curve,Part.Line):
|
||||
print "Arch.getIfcExtrusionData: Warning: unsupported edge type in profile"
|
||||
if curves:
|
||||
# Composite profile
|
||||
ecurves = []
|
||||
last = None
|
||||
import DraftGeomUtils
|
||||
edges = DraftGeomUtils.sortEdges(p.Edges)
|
||||
for e in edges:
|
||||
if isinstance(e.Curve,Part.Circle):
|
||||
import math
|
||||
follow = True
|
||||
if last:
|
||||
if not DraftVecUtils.equals(last,e.Vertexes[0].Point):
|
||||
follow = False
|
||||
last = e.Vertexes[0].Point
|
||||
else:
|
||||
last = e.Vertexes[-1].Point
|
||||
else:
|
||||
last = e.Vertexes[-1].Point
|
||||
p1 = math.degrees(-DraftVecUtils.angle(e.Vertexes[0].Point.sub(e.Curve.Center)))
|
||||
p2 = math.degrees(-DraftVecUtils.angle(e.Vertexes[-1].Point.sub(e.Curve.Center)))
|
||||
da = DraftVecUtils.angle(e.valueAt(e.FirstParameter+0.1).sub(e.Curve.Center),e.Vertexes[0].Point.sub(e.Curve.Center))
|
||||
if p1 < 0:
|
||||
p1 = 360 + p1
|
||||
if p2 < 0:
|
||||
p2 = 360 + p2
|
||||
if da > 0:
|
||||
follow = not(follow)
|
||||
if CURVEMODE == "CARTESIAN":
|
||||
# BUGGY
|
||||
p1 = getTuples(e.Vertexes[0].Point,scale)
|
||||
p2 = getTuples(e.Vertexes[-1].Point,scale)
|
||||
ecurves.append(["arc",getTuples(e.Curve.Center,scale),e.Curve.Radius*scale,[p1,p2],follow,CURVEMODE])
|
||||
else:
|
||||
verts = [vertex.Point for vertex in e.Vertexes]
|
||||
if last:
|
||||
if not DraftVecUtils.equals(last,verts[0]):
|
||||
verts.reverse()
|
||||
last = e.Vertexes[0].Point
|
||||
else:
|
||||
last = e.Vertexes[-1].Point
|
||||
else:
|
||||
last = e.Vertexes[-1].Point
|
||||
ecurves.append(["line",[getTuples(vert,scale) for vert in verts]])
|
||||
return "composite", ecurves, getTuples(v,scale), d
|
||||
else:
|
||||
# Polyline profile
|
||||
return "polyline", getTuples(p,scale), getTuples(v,scale), d
|
||||
return None
|
||||
|
||||
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."""
|
||||
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
|
||||
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 getIfcElevation(obj):
|
||||
"""getIfcElevation(obj): Returns the lowest height (Z coordinate) of this object"""
|
||||
if obj.isDerivedFrom("Part::Feature"):
|
||||
b = obj.Shape.BoundBox
|
||||
return b.ZMin
|
||||
return 0
|
||||
|
||||
|
||||
def explore(filename=None):
|
||||
"explore the contents of an ifc file in a Qt dialog"
|
||||
if not filename:
|
||||
|
|
Loading…
Reference in New Issue
Block a user