Merge branch 'master' of https://github.com/FreeCAD/FreeCAD
This commit is contained in:
commit
78e9319587
|
@ -324,9 +324,11 @@ class _ArchDrawingView:
|
|||
svg = svg.replace('SWPlaceholder', str(linewidth*st) + 'px')
|
||||
svg = svg.replace('DAPlaceholder', str(da))
|
||||
if hasattr(self,"spaces"):
|
||||
if round(self.direction.getAngle(FreeCAD.Vector(0,0,1)),Draft.precision()) in [0,round(math.pi,Draft.precision())]:
|
||||
if self.spaces and round(self.direction.getAngle(FreeCAD.Vector(0,0,1)),Draft.precision()) in [0,round(math.pi,Draft.precision())]:
|
||||
svg += '<g transform="scale(1,-1)">'
|
||||
for s in self.spaces:
|
||||
svg += Draft.getSVG(s,scale=obj.Scale,fontsize=obj.FontSize.Value,direction=self.direction)
|
||||
svg += '</g>'
|
||||
result = ''
|
||||
result += '<g id="' + obj.Name + '"'
|
||||
result += ' transform="'
|
||||
|
@ -345,7 +347,7 @@ class _ArchDrawingView:
|
|||
if hasattr(obj,"Source"):
|
||||
if obj.Source:
|
||||
if obj.Source.Objects:
|
||||
objs = Draft.getGroupContents(obj.Source.Objects,walls=True)
|
||||
objs = Draft.getGroupContents(obj.Source.Objects,walls=True,addgroups=True)
|
||||
objs = Draft.removeHidden(objs)
|
||||
# separate spaces
|
||||
self.spaces = []
|
||||
|
|
|
@ -2120,9 +2120,9 @@ def getSVG(obj,scale=1,linewidth=0.35,fontsize=12,fillstyle="shape color",direct
|
|||
p1 = p2.add(FreeCAD.Vector(obj.ViewObject.Proxy.header.translation.getValue().getValue()))
|
||||
l = obj.ViewObject.LineSpacing/2.0
|
||||
j = obj.ViewObject.TextAlign
|
||||
svg += getText(c,f1,n,a,getProj(p1),t1,l,j,flip=False)
|
||||
svg += getText(c,f1,n,a,getProj(p1),t1,l,j,flip=True)
|
||||
if t2:
|
||||
svg += getText(c,fontsize,n,a,getProj(p2),t2,l,j,flip=False)
|
||||
svg += getText(c,fontsize,n,a,getProj(p2),t2,l,j,flip=True)
|
||||
|
||||
elif obj.isDerivedFrom('Part::Feature'):
|
||||
if obj.Shape.isNull():
|
||||
|
|
|
@ -152,6 +152,9 @@ class FemTools(QtCore.QRunnable, QtCore.QObject):
|
|||
## @var mesh
|
||||
# mesh of the analysis. Used to generate .inp file and to show results
|
||||
self.mesh = None
|
||||
## @var materials
|
||||
# set of materials from the analysis. Updated with update_objects
|
||||
# Induvidual materials are "App::MaterialObjectPython" type
|
||||
self.materials = []
|
||||
## @var fixed_constraints
|
||||
# set of fixed constraints from the analysis. Updated with update_objects
|
||||
|
@ -165,7 +168,13 @@ class FemTools(QtCore.QRunnable, QtCore.QObject):
|
|||
# set of pressure constraints from the analysis. Updated with update_objects
|
||||
# Individual constraints are "Fem::ConstraintPressure" type
|
||||
self.pressure_constraints = []
|
||||
## @var beam_sections
|
||||
# set of beam sections from the analyis. Updated with update_objects
|
||||
# Individual beam sections are Proxy.Type "FemBeamSection"
|
||||
self.beam_sections = []
|
||||
## @var shell_thicknesses
|
||||
# set of shell thicknesses from the analyis. Updated with update_objects
|
||||
# Individual shell thicknesses are Proxy.Type "FemShellThickness"
|
||||
self.shell_thicknesses = []
|
||||
|
||||
for m in self.analysis.Member:
|
||||
|
@ -187,11 +196,11 @@ class FemTools(QtCore.QRunnable, QtCore.QObject):
|
|||
PressureObjectDict = {}
|
||||
PressureObjectDict['Object'] = m
|
||||
self.pressure_constraints.append(PressureObjectDict)
|
||||
elif hasattr(m, "Proxy") and m.Proxy.Type == 'FemBeamSection':
|
||||
elif hasattr(m, "Proxy") and m.Proxy.Type == "FemBeamSection":
|
||||
beam_section_dict = {}
|
||||
beam_section_dict['Object'] = m
|
||||
self.beam_sections.append(beam_section_dict)
|
||||
elif hasattr(m, "Proxy") and m.Proxy.Type == 'FemShellThickness':
|
||||
elif hasattr(m, "Proxy") and m.Proxy.Type == "FemShellThickness":
|
||||
shell_thickness_dict = {}
|
||||
shell_thickness_dict['Object'] = m
|
||||
self.shell_thicknesses.append(shell_thickness_dict)
|
||||
|
|
|
@ -594,19 +594,19 @@ void ViewProviderFemMesh::setDisplacementByNodeIdHelper(const std::vector<Base::
|
|||
applyDisplacementToNodes(1.0);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void ViewProviderFemMesh::resetDisplacementByNodeId(void)
|
||||
{
|
||||
applyDisplacementToNodes(0.0);
|
||||
DisplacementVector.clear();
|
||||
}
|
||||
/// reaply the node displacement with a certain factor and do a redraw
|
||||
void ViewProviderFemMesh::applyDisplacementToNodes(double factor)
|
||||
{
|
||||
if(DisplacementVector.size() == 0)
|
||||
return;
|
||||
|
||||
float x,y,z;
|
||||
}
|
||||
/// reaply the node displacement with a certain factor and do a redraw
|
||||
void ViewProviderFemMesh::applyDisplacementToNodes(double factor)
|
||||
{
|
||||
if(DisplacementVector.size() == 0)
|
||||
return;
|
||||
|
||||
float x,y,z;
|
||||
// set the point coordinates
|
||||
long sz = pcCoords->point.getNum();
|
||||
SbVec3f* verts = pcCoords->point.startEditing();
|
||||
|
@ -626,9 +626,9 @@ void ViewProviderFemMesh::applyDisplacementToNodes(double factor)
|
|||
verts[i].setValue(x,y,z);
|
||||
}
|
||||
pcCoords->point.finishEditing();
|
||||
|
||||
DisplacementFactor = factor;
|
||||
}
|
||||
|
||||
DisplacementFactor = factor;
|
||||
}
|
||||
|
||||
void ViewProviderFemMesh::setColorByElementId(const std::map<long,App::Color> &ElementColorMap)
|
||||
{
|
||||
|
@ -779,9 +779,8 @@ void ViewProviderFEMMeshBuilder::createMesh(const App::Property* prop,
|
|||
case 6:// tria face with 6 nodes
|
||||
BndBox.Add(facesHelper[i++].set(6, aFace, aFace->GetID(), 0, aFace->GetNode(0), aFace->GetNode(1), aFace->GetNode(2), aFace->GetNode(3), aFace->GetNode(4), aFace->GetNode(5)));
|
||||
break;
|
||||
|
||||
//unknown case
|
||||
default: assert(0);
|
||||
default://unknown face type
|
||||
throw std::runtime_error("Node count not supported by ViewProviderFemMesh, [3|4|6] are allowed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -134,15 +134,21 @@ class FemTest(unittest.TestCase):
|
|||
return result
|
||||
|
||||
def compare_stats(self, fea, stat_file=None):
|
||||
sf_content_normalised = []
|
||||
if stat_file:
|
||||
sf = open(stat_file, 'r')
|
||||
sf_content = sf.readlines()
|
||||
sf.close()
|
||||
# Force \n line ends
|
||||
for line in sf_content:
|
||||
if line.endswith("\r\n"):
|
||||
line = line[:-2] + '\n'
|
||||
sf_content_normalised.append(line)
|
||||
stat_types = ["U1", "U2", "U3", "Uabs", "Sabs"]
|
||||
stats = []
|
||||
for s in stat_types:
|
||||
stats.append("{}: {}\n".format(s, fea.get_stats(s)))
|
||||
if sf_content != stats:
|
||||
if sf_content_normalised != stats:
|
||||
fcc_print("Expected stats from {}".format(stat_file))
|
||||
fcc_print(sf_content)
|
||||
fcc_print("Stats read from {}.frd file".format(fea.base_name))
|
||||
|
|
|
@ -38,7 +38,14 @@ if open.__module__ == '__builtin__':
|
|||
def readResult(frd_input):
|
||||
frd_file = pyopen(frd_input, "r")
|
||||
nodes = {}
|
||||
elements = {}
|
||||
elements_hexa8 = {}
|
||||
elements_tetra4 = {}
|
||||
elements_tetra10 = {}
|
||||
elements_tria3 = {}
|
||||
elements_tria6 = {}
|
||||
elements_quad4 = {}
|
||||
elements_quad8 = {}
|
||||
elements_seg2 = {}
|
||||
results = []
|
||||
mode_results = {}
|
||||
mode_disp = {}
|
||||
|
@ -70,7 +77,25 @@ def readResult(frd_input):
|
|||
if elements_found and (line[1:3] == "-1"):
|
||||
elem = int(line[4:13])
|
||||
elemType = int(line[14:18])
|
||||
#then the 10 id's for the Tet10 element
|
||||
#then the 8 id's for the HEXA8 element
|
||||
if elements_found and (line[1:3] == "-2") and elemType == 1:
|
||||
node_id_5= int(line[3:13])
|
||||
node_id_6 = int(line[13:23])
|
||||
node_id_7 = int(line[23:33])
|
||||
node_id_8 = int(line[33:43])
|
||||
node_id_1 = int(line[43:53])
|
||||
node_id_2 = int(line[53:63])
|
||||
node_id_3 = int(line[63:73])
|
||||
node_id_4 = int(line[73:83])
|
||||
elements_hexa8[elem] = (node_id_1, node_id_2, node_id_3, node_id_4, node_id_5, node_id_6, node_id_7, node_id_8)
|
||||
#then the 4 id's for the TETRA4 element
|
||||
if elements_found and (line[1:3] == "-2") and elemType == 3:
|
||||
node_id_2 = int(line[3:13])
|
||||
node_id_1 = int(line[13:23])
|
||||
node_id_3 = int(line[23:33])
|
||||
node_id_4 = int(line[33:43])
|
||||
elements_tetra4[elem] = (node_id_1, node_id_2, node_id_3, node_id_4)
|
||||
#then the 10 id's for the TETRA10 element
|
||||
if elements_found and (line[1:3] == "-2") and elemType == 6:
|
||||
node_id_2 = int(line[3:13])
|
||||
node_id_1 = int(line[13:23])
|
||||
|
@ -82,7 +107,46 @@ def readResult(frd_input):
|
|||
node_id_9 = int(line[73:83])
|
||||
node_id_8 = int(line[83:93])
|
||||
node_id_10 = int(line[93:103])
|
||||
elements[elem] = (node_id_1, node_id_2, node_id_3, node_id_4, node_id_5, node_id_6, node_id_7, node_id_8, node_id_9, node_id_10)
|
||||
elements_tetra10[elem] = (node_id_1, node_id_2, node_id_3, node_id_4, node_id_5, node_id_6, node_id_7, node_id_8, node_id_9, node_id_10)
|
||||
#then the 3 id's for the TRIA3 element
|
||||
if elements_found and (line[1:3] == "-2") and elemType == 7:
|
||||
node_id_1 = int(line[3:13])
|
||||
node_id_2 = int(line[13:23])
|
||||
node_id_3 = int(line[23:33])
|
||||
elements_tria3[elem] = (node_id_1, node_id_2, node_id_3)
|
||||
#then the 6 id's for the TRIA6 element
|
||||
if elements_found and (line[1:3] == "-2") and elemType == 8:
|
||||
node_id_1 = int(line[3:13])
|
||||
node_id_2 = int(line[13:23])
|
||||
node_id_3 = int(line[23:33])
|
||||
node_id_4 = int(line[33:43])
|
||||
node_id_5 = int(line[43:53])
|
||||
node_id_6 = int(line[53:63])
|
||||
elements_tria6[elem] = (node_id_1, node_id_2, node_id_3, node_id_4, node_id_5, node_id_6)
|
||||
#then the 4 id's for the QUAD4 element
|
||||
if elements_found and (line[1:3] == "-2") and elemType == 9:
|
||||
node_id_1 = int(line[3:13])
|
||||
node_id_2 = int(line[13:23])
|
||||
node_id_3 = int(line[23:33])
|
||||
node_id_4 = int(line[33:43])
|
||||
elements_quad4[elem] = (node_id_1, node_id_2, node_id_3, node_id_4)
|
||||
#then the 8 id's for the QUAD8 element
|
||||
if elements_found and (line[1:3] == "-2") and elemType == 10:
|
||||
node_id_1 = int(line[3:13])
|
||||
node_id_2 = int(line[13:23])
|
||||
node_id_3 = int(line[23:33])
|
||||
node_id_4 = int(line[33:43])
|
||||
node_id_5 = int(line[43:53])
|
||||
node_id_6 = int(line[53:63])
|
||||
node_id_7 = int(line[63:73])
|
||||
node_id_8 = int(line[73:83])
|
||||
elements_quad8[elem] = (node_id_1, node_id_2, node_id_3, node_id_4, node_id_5, node_id_6, node_id_7, node_id_8)
|
||||
#then the 2 id's for the SEG2 element
|
||||
if elements_found and (line[1:3] == "-2") and elemType == 11:
|
||||
node_id_1 = int(line[3:13])
|
||||
node_id_2 = int(line[13:23])
|
||||
elements_seg2[elem] = (node_id_1, node_id_2)
|
||||
|
||||
#Check if we found new eigenmode
|
||||
if line[5:10] == "PMODE":
|
||||
eigenmode = int(line[30:36])
|
||||
|
@ -129,7 +193,8 @@ def readResult(frd_input):
|
|||
elements_found = False
|
||||
|
||||
frd_file.close()
|
||||
return {'Nodes': nodes, 'Tet10Elem': elements, 'Results': results}
|
||||
return {'Nodes': nodes, 'Hexa8Elem': elements_hexa8, 'Tetra4Elem': elements_tetra4, 'Tetra10Elem': elements_tetra10, 'Tria3Elem': elements_tria3,
|
||||
'Tria6Elem': elements_tria6, 'Quad4Elem': elements_quad4, 'Quad8Elem': elements_quad8, 'Seg2Elem': elements_seg2, 'Results': results}
|
||||
|
||||
|
||||
def calculate_von_mises(i):
|
||||
|
@ -148,17 +213,18 @@ def calculate_von_mises(i):
|
|||
return vm_stress
|
||||
|
||||
|
||||
def importFrd(filename, Analysis=None):
|
||||
def importFrd(filename, analysis=None):
|
||||
m = readResult(filename)
|
||||
MeshObject = None
|
||||
mesh_object = None
|
||||
if(len(m['Nodes']) > 0):
|
||||
import Fem
|
||||
if Analysis is None:
|
||||
AnalysisName = os.path.splitext(os.path.basename(filename))[0]
|
||||
AnalysisObject = FreeCAD.ActiveDocument.addObject('Fem::FemAnalysis', 'Analysis')
|
||||
AnalysisObject.Label = AnalysisName
|
||||
if analysis is None:
|
||||
analysis_name = os.path.splitext(os.path.basename(filename))[0]
|
||||
import MechanicalAnalysis
|
||||
analysis_object = MechanicalAnalysis.makeMechanicalAnalysis('Analysis')
|
||||
analysis_object.Label = analysis_name
|
||||
else:
|
||||
AnalysisObject = Analysis
|
||||
analysis_object = analysis # see if statement few lines later, if not analysis -> no FemMesh object is created !
|
||||
|
||||
if 'Nodes' in m:
|
||||
positions = []
|
||||
|
@ -172,21 +238,51 @@ def importFrd(filename, Analysis=None):
|
|||
z_span = abs(p_z_max - p_z_min)
|
||||
span = max(x_span, y_span, z_span)
|
||||
|
||||
if ('Tet10Elem' in m) and ('Nodes' in m) and (not Analysis):
|
||||
if (not analysis) and ('Nodes' in m) and (('Hexa8Elem' in m) or ('Tetra4Elem' in m) or ('Tetra10Elem' in m) or ('Tria3Elem' in m) or ('Tria6Elem' in m) or ('Quad4Elem' in m) or ('Quad8Elem' in m) or ('Seg2Elem' in m)):
|
||||
mesh = Fem.FemMesh()
|
||||
nds = m['Nodes']
|
||||
|
||||
for i in nds:
|
||||
n = nds[i]
|
||||
mesh.addNode(n[0], n[1], n[2], i)
|
||||
elms = m['Tet10Elem']
|
||||
for i in elms:
|
||||
e = elms[i]
|
||||
elms_hexa8 = m['Hexa8Elem']
|
||||
for i in elms_hexa8:
|
||||
e = elms_hexa8[i]
|
||||
mesh.addVolume([e[0], e[1], e[2], e[3], e[4], e[5], e[6], e[7]], i)
|
||||
elms_tetra4 = m['Tetra4Elem']
|
||||
for i in elms_tetra4:
|
||||
e = elms_tetra4[i]
|
||||
mesh.addVolume([e[0], e[1], e[2], e[3]], i)
|
||||
elms_tetra10 = m['Tetra10Elem']
|
||||
for i in elms_tetra10:
|
||||
e = elms_tetra10[i]
|
||||
mesh.addVolume([e[0], e[1], e[2], e[3], e[4], e[5], e[6], e[7], e[8], e[9]], i)
|
||||
elms_tria3 = m['Tria3Elem']
|
||||
for i in elms_tria3:
|
||||
e = elms_tria3[i]
|
||||
mesh.addFace([e[0], e[1], e[2]], i)
|
||||
elms_tria6 = m['Tria6Elem']
|
||||
for i in elms_tria6:
|
||||
e = elms_tria6[i]
|
||||
mesh.addFace([e[0], e[1], e[2], e[3], e[4], e[5]], i)
|
||||
elms_quad4 = m['Quad4Elem']
|
||||
for i in elms_quad4:
|
||||
e = elms_quad4[i]
|
||||
mesh.addFace([e[0], e[1], e[2], e[3]], i)
|
||||
elms_quad8 = m['Quad8Elem']
|
||||
for i in elms_quad8:
|
||||
e = elms_quad8[i]
|
||||
mesh.addFace([e[0], e[1], e[2], e[3], e[4], e[5], e[6], e[7]], i)
|
||||
elms_seg2 = m['Seg2Elem']
|
||||
for i in elms_seg2:
|
||||
e = elms_seg2[i]
|
||||
mesh.addEdge(e[0], e[1])
|
||||
print ("imported mesh: %d nodes, %d HEXA8, %d TETRA4, %d TETRA10, %d TRIA3, %d TRIA6, %d QUAD4, %d QUAD8, %d SEG2"
|
||||
%(len(nds), len(elms_hexa8), len(elms_tetra4), len(elms_tetra10), len(elms_tria3), len(elms_tria6), len(elms_quad4), len(elms_quad8), len(elms_seg2)))
|
||||
if len(nds) > 0:
|
||||
MeshObject = FreeCAD.ActiveDocument.addObject('Fem::FemMeshObject', 'ResultMesh')
|
||||
MeshObject.FemMesh = mesh
|
||||
AnalysisObject.Member = AnalysisObject.Member + [MeshObject]
|
||||
mesh_object = FreeCAD.ActiveDocument.addObject('Fem::FemMeshObject', 'ResultMesh')
|
||||
mesh_object.FemMesh = mesh
|
||||
analysis_object.Member = analysis_object.Member + [mesh_object]
|
||||
|
||||
for result_set in m['Results']:
|
||||
eigenmode_number = result_set['number']
|
||||
|
@ -215,8 +311,8 @@ def importFrd(filename, Analysis=None):
|
|||
if len(disp) > 0:
|
||||
results.DisplacementVectors = map((lambda x: x * scale), disp.values())
|
||||
results.NodeNumbers = disp.keys()
|
||||
if(MeshObject):
|
||||
results.Mesh = MeshObject
|
||||
if(mesh_object):
|
||||
results.Mesh = mesh_object
|
||||
|
||||
stress = result_set['stress']
|
||||
if len(stress) > 0:
|
||||
|
@ -258,11 +354,11 @@ def importFrd(filename, Analysis=None):
|
|||
z_min, z_avg, z_max,
|
||||
a_min, a_avg, a_max,
|
||||
s_min, s_avg, s_max]
|
||||
AnalysisObject.Member = AnalysisObject.Member + [results]
|
||||
analysis_object.Member = analysis_object.Member + [results]
|
||||
|
||||
if(FreeCAD.GuiUp):
|
||||
import FemGui
|
||||
FemGui.setActiveAnalysis(AnalysisObject)
|
||||
FemGui.setActiveAnalysis(analysis_object)
|
||||
|
||||
|
||||
def insert(filename, docname):
|
||||
|
|
Loading…
Reference in New Issue
Block a user