Skip to content

Commit

Permalink
Merge branch 'Gmsh2' into link3
Browse files Browse the repository at this point in the history
  • Loading branch information
KeithSloan committed Jun 21, 2021
2 parents 8b7d3fb + 2f6e8e6 commit fb5172d
Show file tree
Hide file tree
Showing 7 changed files with 273 additions and 212 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
Utils/*.step
freecad/__pycache__/
.DS_Store
27 changes: 14 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ To resolve you have to install the lxml library where FreeCAD can find it see
the required libraries section of this README.

## *** Note there is a regression with STEP export ***
With OCC 7.4.0 as used in FreeCAD 0.19.2
With OCC 7.5.0 and 7.5.1 as used in FreeCAD 0.19.2

## *** All Operating Systems - Problem export of Rotations ***

Expand Down Expand Up @@ -266,19 +266,20 @@ created GDML Tessellated Object
### Tessellate with Gmsh
![GDML Tessellate_Gmsh](freecad/gdml/Resources/icons/GDML_Tessellate_Gmsh.svg)

If the selected FreeCAD object has a Shape or Mesh then a GDML Tessellated Object is created by using gmsh.
If the selected FreeCAD object has a Shape or Mesh then a Gmsh Panel is displayed in the Task Window.

The initial mesh size is determined by the shapes bounding box divided by 10.

You can **remesh** a copy of the original object by changing the properties of the created GDMLTesselate Object
m_max Length - CharacteristicLengthMax
m_curve Len - CharacteristicLengthFromCurvature
m_point Len - CharacteristicLengthFromPoints
and then changing the **m_Remesh** property to True.
The panel displays
1) Bounding box information for the selected Object
2) Type of Mesh
3) Input parameters for the Gmsh operation
4) Action 'Mesh' button

Clicking on the 'Mesh' button a GDML_Tessellate_Gmsh Object is created and Mesh info is added to the panel.
The input parameters can be changed and another Gmsh operation performed.

Note: For some reason there appears to be a delay in updating the new number of vertex. facets counts displayed.
Once happy with the Mesh, then Object being meshed can be deleted before exporting to the GDML format.
The panel needs to be closed before working on another object

### FC Mesh to GDML Tessellated
![GDML FC-Mesh2Tess-Icon](freecad/gdml/Resources/icons/GDML_Mesh2Tess.svg) Mesh to GDML Tessellated
Expand Down Expand Up @@ -568,7 +569,7 @@ For NIST Materials database see http://physics.nist.gov/PhysRefData
* Hilden Timo
* Atanu Quant

* FreeCAD forum members (Applogies if I left anybody off ) :
* FreeCAD forum members (Apologies if I left anybody off ) :

* wmayer
* Joel_graff
Expand Down
202 changes: 113 additions & 89 deletions freecad/gdml/GDMLCommands.py
Original file line number Diff line number Diff line change
Expand Up @@ -742,87 +742,111 @@ def isAllowedAlterView(self):
def isAllowedAlterDocument(self):
return True

def processMesh(self, vertex, facets) :
from .GDMLObjects import ViewProvider

print('Update Tessellated Object')
print(dir(self))
print('Object Name ' +self.obj.Name)
print('Object Type ' +self.obj.TypeId)
if hasattr(self.obj,'Proxy') :
print('Proxy')
print(self.obj.Proxy.Type)
if self.obj.Proxy.Type == 'GDMLGmshTessellated' or \
self.obj.Proxy.Type == 'GDMLTessellated' :
self.obj.Proxy.updateParams(vertex,facets)
#print(dir(self.form))
print('Vertex : '+str(len(vertex)))
print('Facets : '+str(len(facets)))
# Update Info of GDML Tessellated Object
if self.tess is not None :
print('Tesselated Name '+self.tess.Name)
print('Update parms : '+self.tess.Name)
if hasattr(self.tess,'Proxy') : # If GDML object has Proxy
print(dir(self.tess.Proxy))
self.tess.Proxy.updateParams(vertex,facets)
else :
self.tess.updateParams(vertex,facets)
#print('Update parms : '+self.tess.Name)
#self.tess.updateParams(vertex,facets)
#self.form.Vertex.value.setText(QtCore.QString(len(vertex)))
self.form.Vertex.value.setText(str(len(vertex)))
#self.form.Facets.value.setText(QtCore.QString(len(facets)))
self.form.Facets.value.setText(str(len(facets)))

if FreeCAD.GuiUp :
if self.tess is not None :
self.obj.ViewObject.Visibility = False
ViewProvider(self.tess.ViewObject)
self.tess.ViewObject.DisplayMode = "Wireframe"
self.tess.recompute()
#FreeCAD.ActiveDocument.recompute()
else :
print('Recompute : '+self.obj.Name)
self.obj.recompute()
self.obj.ViewObject.Visibility = True
FreeCADGui.SendMsgToActiveView("ViewFit")
FreeCADGui.updateGui()

def actionMesh(self) :
from .GmshUtils import initialize, meshObject, \
getVertex, getFacets, getMeshLen, printMeshInfo, printMyInfo
from .GDMLObjects import GDMLGmshTessellated, GDMLTriangular, \
ViewProvider, ViewProviderExtension
from .GDMLObjects import GDMLGmshTessellated, GDMLTriangular
print('Action Gmsh : '+self.obj.Name)
initialize()
typeDict = {0:6,1:8,2:9}
print(dir(self))
print('Object '+self.obj.Name)
if self.tess is not None :
print('Tessellated '+self.tess.Name)
ty = typeDict[self.form.type.currentIndex()]
ml = self.form.maxLen.value.text()
cl = self.form.curveLen.value.text()
pl = self.form.pointLen.value.text()
print('type : '+str(ty)+' ml : '+ml+' cl : '+cl+' pl : '+pl)
existing = False
if hasattr(self.obj,'Proxy') :
print('has proxy')
if hasattr(self.obj.Proxy,'SourceObj') :
print('Has source Object')
existing = True
if meshObject(self.obj.Proxy.SourceObj,2,ty,\
float(ml),float(cl),float(pl)) == True :
facets = getFacets()
vertex = getVertex()
self.tess = self.obj
else :
if meshObject(self.obj,2,ty, \
float(ml),float(cl),float(pl)) == True :
facets = getFacets()
vertex = getVertex()
if self.tess is None :
name ='GDMLTessellate_'+self.obj.Name
parent = None
if hasattr(self.obj,'InList') :
if len(self.obj.InList) > 0 :
parent = self.obj.InList[0]
self.tess = parent.newObject('Part::FeaturePython',name)
if parent == None :
self.tess = FreeCAD.ActiveDocument.addObject( \
'Part::FeaturePython',name)
GDMLGmshTessellated(self.tess,self.obj,getMeshLen(self.obj),vertex, facets, \
self.processMesh(vertex,facets)
return

if meshObject(self.obj,2,ty, \
float(ml),float(cl),float(pl)) == True :
facets = getFacets()
vertex = getVertex()
if self.tess is None :
name ='GDMLTessellate_'+self.obj.Name
parent = None
if hasattr(self.obj,'InList') :
if len(self.obj.InList) > 0 :
parent = self.obj.InList[0]
self.tess = parent.newObject('Part::FeaturePython',name)
if parent == None :
self.tess = FreeCAD.ActiveDocument.addObject( \
'Part::FeaturePython',name)
GDMLGmshTessellated(self.tess,self.obj,getMeshLen(self.obj),vertex, facets, \
"mm", getSelectedMaterial())
print('Check Form')
#print(dir(self.form))
if not hasattr(self.form,'infoGroup') :
self.form.infoGroup = QtGui.QGroupBox('Mesh Information')
print('Mesh Info Layout')
layMeshInfo=QtGui.QHBoxLayout()
layMeshInfo.addWidget(self.form.Vertex)
layMeshInfo.addWidget(self.form.Facets)
#layMeshInfo.addWidget(self.form.Nodes)
self.form.infoGroup.setLayout(layMeshInfo)
self.form.Vlayout.addWidget(self.form.infoGroup)
#self.form.setLayout(self.form.Vlayout)

print('Update Tessellated Object')
#print(dir(self.form))
print('Vertex : '+str(len(vertex)))
print('Facets : '+str(len(facets)))
if existing == True :
self.obj.Proxy.updateParams(vertex,facets)
else :
self.tess.Proxy.updateParams(vertex,facets)
#self.form.Vertex.value.setText(QtCore.QString(len(vertex)))
self.form.Vertex.value.setText(str(len(vertex)))
#self.form.Facets.value.setText(QtCore.QString(len(facets)))
self.form.Facets.value.setText(str(len(facets)))

if FreeCAD.GuiUp :
print(self.tess)
print('Visibility : '+self.tess.Name)
if existing == True :
print('Recompute : '+self.obj.Name)
self.obj.recompute()
self.obj.ViewObject.Visibility = True
else :
self.obj.ViewObject.Visibility = False
ViewProvider(self.tess.ViewObject)
self.tess.ViewObject.DisplayMode = "Wireframe"
self.tess.recompute()
#FreeCAD.ActiveDocument.recompute()
FreeCADGui.SendMsgToActiveView("ViewFit")
FreeCADGui.updateGui()
self.processMesh(vertex,facets)

print('Check Form')
#print(dir(self.form))
if not hasattr(self.form,'infoGroup') :
self.form.infoGroup = QtGui.QGroupBox('Mesh Information')
print('Mesh Info Layout')
layMeshInfo=QtGui.QHBoxLayout()
layMeshInfo.addWidget(self.form.Vertex)
layMeshInfo.addWidget(self.form.Facets)
#layMeshInfo.addWidget(self.form.Nodes)
self.form.infoGroup.setLayout(layMeshInfo)
self.form.Vlayout.addWidget(self.form.infoGroup)
#self.form.setLayout(self.form.Vlayout)
self.processMesh(vertex,facets)

def leaveEvent(self, event) :
print('Leave Event II')
Expand Down Expand Up @@ -971,37 +995,37 @@ def Activated(self) :

for obj in FreeCADGui.Selection.getSelection():
print('Action Tessellate 2 Mesh')
#print(dir(obj.Proxy))
print(obj.Proxy.Type)
mesh = None
if obj.Proxy.Type == 'GDMLTessellated' :
print('Tessellated2Mesh')
mesh = Tessellated2Mesh(obj)
if hasattr(obj,'Proxy') :
if hasattr(obj.Proxy,'Type') :
mesh = None
if obj.Proxy.Type == 'GDMLTessellated' :
print('Tessellated2Mesh')
mesh = Tessellated2Mesh(obj)

if obj.Proxy.Type == 'GDMLGmshTessellated' :
print('GmshTessellated2Mesh')
mesh = Tessellated2Mesh(obj)
if obj.Proxy.Type == 'GDMLGmshTessellated' :
print('GmshTessellated2Mesh')
mesh = Tessellated2Mesh(obj)

if obj.Proxy.Type == 'GDMLTetrahedron' :
print('Tetrahedron2Mesh')
mesh = Tetrahedron2Mesh(obj)

if mesh != None :
print('Add Mesh')
parent = None
if hasattr(obj,'InList') :
if len(obj.InList) > 0 :
parent = obj.InList[0]
mshObj = parent.newObject('Mesh::Feature',obj.Name)
if parent == None :
mshObj = FreeCAD.ActiveDocument.addObject( \
if obj.Proxy.Type == 'GDMLTetrahedron' :
print('Tetrahedron2Mesh')
mesh = Tetrahedron2Mesh(obj)

if mesh != None :
print('Add Mesh')
parent = None
if hasattr(obj,'InList') :
if len(obj.InList) > 0 :
parent = obj.InList[0]
mshObj = parent.newObject('Mesh::Feature',obj.Name)
if parent == None :
mshObj = FreeCAD.ActiveDocument.addObject( \
'Mesh::Feature',obj.Name)
mshObj.Mesh = mesh
if FreeCAD.GuiUp :
obj.ViewObject.Visibility = False
mshObj.ViewObject.DisplayMode = "Wireframe"
FreeCAD.ActiveDocument.recompute()
FreeCADGui.SendMsgToActiveView("ViewFit")
mshObj.Mesh = mesh
if FreeCAD.GuiUp :
obj.ViewObject.Visibility = False
mshObj.ViewObject.DisplayMode = "Wireframe"
FreeCAD.ActiveDocument.recompute()
FreeCADGui.SendMsgToActiveView("ViewFit")

def GetResources(self):
return {'Pixmap' : 'GDML_Tess2Mesh', 'MenuText': \
Expand Down
7 changes: 1 addition & 6 deletions freecad/gdml/GDMLObjects.py
Original file line number Diff line number Diff line change
Expand Up @@ -305,15 +305,13 @@ def __getstate__(self):
return {'type' : self.Type }
else :
pass


def __setstate__(self,arg):
'''When restoring the serialized object from document we have the chance to set some internals here.\
Since no data were serialized nothing needs to be done here.'''
if arg is not None :
self.Type = arg['type']


class GDMLArb8(GDMLsolid) : # Thanks to Dam Lamb
def __init__(self, obj, v1x, v1y, v2x, v2y, v3x, v3y, v4x, v4y, \
v5x, v5y, v6x, v6y, v7x, v7y, v8x, v8y, dz, \
Expand Down Expand Up @@ -2282,9 +2280,6 @@ def __init__(self, obj, vertex, facets, lunit, material, colour = None) :
obj.ViewObject.ShapeColor = colourMaterial(material)
else :
obj.ViewObject.ShapeColor = colourMaterial(material)
# Suppress Placement - position & Rotation via parent App::Part
# this makes Placement via Phyvol easier and allows copies etc
#obj.addExtension('App::GroupExtensionPython')
self.Type = 'GDMLTessellated'
self.Vertex = vertex
self.Facets = facets
Expand All @@ -2297,7 +2292,7 @@ def onChanged(self, fp, prop):
'''Do something when a property has changed'''
#print(fp.Label+" State : "+str(fp.State)+" prop : "+prop)
if 'Restore' in fp.State :
return
return

if prop in ['material'] :
if FreeCAD.GuiUp :
Expand Down
7 changes: 5 additions & 2 deletions freecad/gdml/GmshUtils.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ def meshObjMesh(obj,dim) :
def meshObject(obj, dim, algol, lm, lc, lp) :
# Create gmsh from shape or mesh
# Clear any previous models
print('gmsh Clear')
print('mesh Object - first Clear')
gmsh.clear()
setMeshParms(algol,lm, lc, lp)
if hasattr(obj,'Shape') :
Expand Down Expand Up @@ -225,6 +225,9 @@ def getFacets() :
# Element type 0 point, 1 line, 2 triangle 3 quadrangle 4 tetrahedron
# Face types 3 triangle 4 quadrangle
# Get Triangle Facets
# Get Elements
#eTypes, tags, faceNodes = gmsh.model.mesh.getElements(-1,-1)
#print(eTypes[0:3])
tags, faceNodes = gmsh.model.mesh.getElementsByType(2)
#print('faceNodes datatype : '+str(faceNodes.dtype))
faceNodes = faceNodes.astype('int32')
Expand Down Expand Up @@ -274,7 +277,7 @@ def addFacet(msh, v0,v1,v2) :
#print(v0)
#print(v1)
#print(v2)
msh.addFacet(v0,v1,v2)
msh.addFacet(FreeCAD.Vector(v0),FreeCAD.Vector(v1),FreeCAD.Vector(v2))

def Tessellated2Mesh(obj) :
import Mesh
Expand Down
2 changes: 1 addition & 1 deletion freecad/gdml/exportGDML.py
Original file line number Diff line number Diff line change
Expand Up @@ -1184,7 +1184,7 @@ def processMaterialObject(obj) :
if hasattr(obj,'Dvalue') :
D.set('value',str(obj.Dvalue))

if hasattr(obj,'Tunit') :
if hasattr(obj,'Tunit') and hasattr(obj,'Tvalue') :
ET.SubElement(item,'T',{'unit': obj.Tunit, \
'value': str(obj.Tvalue)})

Expand Down
Loading

0 comments on commit fb5172d

Please sign in to comment.