Skip to content

Commit

Permalink
Version 2 (#36)
Browse files Browse the repository at this point in the history
* beso files added

* v1.0

* Delete fembygen/__pycache__ directory

pycache deleted

* names were changed with Topology

* Beso Ui

* new file name was given

* Beso conf file

* Bug fix

* Beso now plots in FreeCAD

* Old files were deleted

* topology interface created (#6)

* beso files added

* v1.0

* Delete fembygen/__pycache__ directory

pycache deleted

* names were changed with Topology

* Beso Ui

* new file name was given

* Beso conf file

* Bug fix

* Beso now plots in FreeCAD

* Old files were deleted

* variable names were changed

* some lines were temporarily converted to comment line

* The interface's problem has been resolved and variable names have been adjusted. (#13)

* beso files added

* v1.0

* Delete fembygen/__pycache__ directory

pycache deleted

* names were changed with Topology

* Beso Ui

* new file name was given

* Beso conf file

* Bug fix

* Beso now plots in FreeCAD

* Old files were deleted

* variable names were changed

* some lines were temporarily converted to comment line

---------

Co-authored-by: Serdar Turgut İnce <[email protected]>

* small refactoring

* comment

* Dev (#14)

* better error handling

* multithreading for creating generations

* version name changed

* added new line

* Update Generate.py and Generate.ui. Create Design.py  (#10)

* Devbetter error handling (#9)

* better error handling

* multithreading for creating generations

* version name changed

* added new line

* Update Generate.py

* Create Design.py

* Update Generate.ui

---------

Co-authored-by: Serdar Turgut İnce <[email protected]>

* Last Update to Generate.py, Generate.ui and Design.py (#11)

* Devbetter error handling (#9)

* better error handling

* multithreading for creating generations

* version name changed

* added new line

* Update Generate.py

* Create Design.py

* Update Generate.ui

* Update Design.py

* Update Generate.py and added full factorial design

* Last Update Generate.ui

---------

Co-authored-by: Serdar Turgut İnce <[email protected]>

* added taguchi optimization design in Generate.py and Generate.ui (#12)

* Add files via upload

* Add files via upload

---------

Co-authored-by: Serdar Turgut İnce <[email protected]>

* Update metadata.txt

* Update README.md

---------

Co-authored-by: AhmetOzkanCanli <[email protected]>
Co-authored-by: omer1911 <[email protected]>

* fixed some errors

* fixed conf file error

* changed plotting style with multiple plots on 1 subplot. (#16)

* added missin domain_thickness

* added break command to exit loop when freecad closed.

* multiple plot in 1 subplot

* fixed overwrite bug to generate

* added latinhypercube

* Update Generate.py

added latin hyper cube to selection

* Update Generate.ui

* arrange the files and fixed libray error

* new ui of Beso (#17)

* added missin domain_thickness

* added break command to exit loop when freecad closed.

* multiple plot in 1 subplot

* Beso.ui has been altered to simplify

* new feature has been added

---------

Co-authored-by: V-ulkan <[email protected]>
Co-authored-by: V-ulkan <[email protected]>

* adding slider to get previous results

* fixed slider error

* fix typo

* storing Generation Method in Generation object

* added extended settings gui for DOE

* added box behnken and composite settings

* added lhs settings gui

* [BETA] beso conf variables as a topology property

* a toplogy bug and generate features added

* number of cpu added generate to run  parallel

* ignore unnecessary files

* del conf file and confs. added as prop. of object

* alone topology is working now

* working for with/without generative design

* handled scipy dependency

* a possible error for solver new framework solved

* shw tplgy clearly and create seperate tplgy files.

* Fix stress limit error

* fixed filter list storing bug

* fixed some topology gui problems

* Topology (#18)

* Update Initiate.py

Error handling, documentation, spreadsheet look

* Update Alias.py

Error handling, documentation

* Update Initiate.py and Alias.py

- Parameters "Name"
- Parameters sheet opens directly

* fix some small code for readiblity

* simlify beso

* topology gui small bug solved

* [Alpha] Beso simplification

* [Alpha] small fix

* trying to fix elset name error

* Add files via upload

* commit

* update createGeo.ui

* Add files via upload (#24)

* Devbetter error handling (#9)

* better error handling

* multithreading for creating generations

* version name changed

* added new line

* Create FUNDING.yml

* trying to fix elset name error

* Add files via upload

* commit

* update createGeo.ui

---------

Co-authored-by: Serdar Turgut İnce <[email protected]>

* better handling of activedocument

* updated "createGeo" Commend

* modified "createGeo" commend (#25)

* updated "createGeo" commend

* createGeo commend modified

* added "Topology" task

* Interface edited.

* added "gmsh" in createGeo commend (#26)

* updated "createGeo" commend

* createGeo commend modified

* added "Topology" task

* Interface edited.

* added "gmsh"

* updated "ui"  file and added missing files

---------

Co-authored-by: Serdar Turgut İnce <[email protected]>

* bug fixed

* Addockwidget and Topology bug fixed (#30)

* updated "createGeo" commend

* createGeo commend modified

* bug fixed

* bug fixed

* Update createGeo.py and fixed pull request bug

* Update createGeo.ui

* added "preserve and obstacle" widget and task (#32)

* updated "createGeo" commend

* createGeo commend modified

* bug fixed

* bug fixed

* Created "preserve and obstacle"bodises selection

* added widget "preserve and obstacle bodies"

* added mesh smooth for every step and updated createGeo.ui (#34)

* updated "createGeo" Commend

* bug fixed

* edited topology files

* edited Common.py

* added logging and delete topology history (#35)

* updated "createGeo" Commend

* bug fixed

* edited topology files

* edited Common.py

* added basic and advanced topology and logger task

* updated logging task

* Update Topology.py

* some small fix

---------

Co-authored-by: V-ulkan <[email protected]>
Co-authored-by: V-ulkan <[email protected]>
Co-authored-by: AhmetOzkanCanli <[email protected]>
Co-authored-by: omer1911 <[email protected]>
Co-authored-by: Steven Quirin <[email protected]>
  • Loading branch information
6 people authored Nov 16, 2023
1 parent 9c5723d commit 3225d01
Show file tree
Hide file tree
Showing 49 changed files with 11,561 additions and 175 deletions.
13 changes: 0 additions & 13 deletions .github/FUNDING.yml

This file was deleted.

2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*.pyc
__pychache__
11 changes: 7 additions & 4 deletions InitGui.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
import FreeCAD, FreeCADGui


class FEMbyGEN(Workbench):
MenuText = "FEMbyGEN"
ToolTip = "Parametric FEM analysis"
Icon = FreeCAD.getUserAppDataDir() + "Mod/FEMbyGEN/icon.svg"

def Initialize(self):
"""This function is executed when FreeCAD starts"""
#import MyModuleA, MyModuleB # import here all the needed files that create your FreeCAD commands
from fembygen import Initiate, Alias, Generate, FEA, Results
FreeCADGui.addIconPath(FreeCAD.getUserAppDataDir() + "Mod/FEMbyGEN/")
self.list = ["Initiate", "Alias","Generate", "FEA", "Results"] # A list of command names created in the line above

from fembygen import Initiate, Alias, Generate, FEA,createGeo, Results, Topology
FreeCADGui.addIconPath(FreeCAD.getUserAppDataDir() + "Mod/FEMbyGEN/fembygen/icons/")

self.list = ["Initiate", "Alias","Generate", "FEA","createGeo", "Results", "Topology"] # A list of command names created in the line above

self.appendToolbar("Commands", self.list) # creates a new toolbar with your commands
self.appendMenu("FEMbyGEN", self.list) # creates a new menu

Expand Down
12 changes: 9 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ This project was devoloped based on [Rahul](https://github.com/MightyBucket/) Ma
This folder contains the code for a workbench plug-in for FreeCAD. Therefore you must have FreeCAD installed to use it.
FreeCAD 0.20 can be downloaded for free from https://www.freecadweb.org/

Once installed, you can add this webpage address to Edit > Preferences > Addon Manager > Custom repository in Freecad. Second method after downloading this repository and manually copy the 'FembyGen' folder to the user 'Mod' directory for FreeCAD. This is normally found in the following directory:
You can install it by addon manager in the FreeCAD or you can add this webpage address to Edit > Preferences > Addon Manager > Custom repository in Freecad. Second method after downloading this repository and manually copy the 'FembyGen' folder to the user 'Mod' directory for FreeCAD. This is normally found in the following directory:

in Windows:
`C:\Users\*UserName*\AppData\Roaming\FreeCAD\Mod
Expand All @@ -32,5 +32,11 @@ After then everything is easy, just click generate button, to create your new ge

Then you can use Fea button to fem simulations of all created generations.

At the end, you can check all results by clicking results button. You can open the generated files by clicking table rows of results Gui. And all results also will come to master file, you can check tree view for that.

You can check all results by clicking results button. You can open the generated files by clicking table rows of results Gui. And all results also will come to master file, you can check tree view for that.

It offers also a suggesting optimum geometry for your boundry conditions. By clicking creategeo button, You can choose your boundries such as supports, pressures,forces and the function will create an optimum body for you.

By clicking toplogy button you can run a topology optimization analysis.

## Requirements
- scipy
26 changes: 17 additions & 9 deletions fembygen/Alias.py
Original file line number Diff line number Diff line change
@@ -1,35 +1,43 @@
import FreeCAD
import FreeCADGui
import os

LOCATION = 'Mod/FEMbyGEN/fembygen'
MAX_NUM_PARAMETER = 10 # maximum number of parameters

class AliasCommand():
"""Analyse the generated parts"""

def GetResources(self):
return {'Pixmap': FreeCAD.getUserAppDataDir() +'Mod/FEMbyGEN/fembygen/Alias.svg', # the name of a svg file available in the resources
return {'Pixmap': os.path.join(FreeCAD.getUserAppDataDir(), LOCATION, 'icons/Alias.svg'),
'Accel': "Shift+A", # a default shortcut (optional)
'MenuText': "Alias",
'ToolTip': "Alias in spreadsheet"}
'MenuText': "Set alias",
'ToolTip': "Set the alias from Parameters Name cells"}

def Activated(self):
return AliasPanel()

def IsActive(self):
"""Here you can define if the command must be active or not (greyed) if certain conditions
are met or not. This function is optional."""
return True
doc = FreeCAD.ActiveDocument
return doc is not None and hasattr(doc, 'Parameters')


class AliasPanel:
def __init__(self):
for i in range(10):
doc = FreeCAD.ActiveDocument
aliasedNum = 0
for i in range(MAX_NUM_PARAMETER):
try:
FreeCAD.ActiveDocument.Parameters.setAlias(
f'C{i+2}', FreeCAD.ActiveDocument.Parameters.get(f'B{i+2}'))
FreeCAD.ActiveDocument.Parameters.recompute()
print("Parameters names and sizes are aliased")
doc.Parameters.setAlias(f'C{i+2}', doc.Parameters.get(f'B{i+2}'))
except:
pass
else:
aliasedNum += 1
doc.Parameters.recompute()
FreeCAD.Console.PrintMessage(
f"{aliasedNum} parameters are aliased and can be used in expressions.\n")


FreeCADGui.addCommand('Alias', AliasCommand())
65 changes: 53 additions & 12 deletions fembygen/Common.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import numpy as np
import operator
import glob
import Fem
import FreeCADGui as Gui


def checkGenerations(workingDir):
Expand Down Expand Up @@ -49,10 +51,12 @@ def searchAnalysed(master):
if obj.TypeId == "Fem::FemAnalysis": # to choose analysis objects
lc += 1
analysisfolder = os.path.join(
workingDir + f"/Gen{i}/loadCase{lc}/")
workingDir + f"/Gen{i}/loadCase_{lc}/")
print("analysisfolder", analysisfolder)
try:
# This returns an exception if analysis failed for this .frd file, because there is no results data
FRDPath = glob.glob(analysisfolder + "*.frd")[0]
print("frdpadh", FRDPath)
try:
with open(FRDPath, "r") as file:
file.readline().decode().strip()
Expand All @@ -73,20 +77,11 @@ def searchAnalysed(master):

def checkAnalyses(master):
statuses = master.FEA.Status
numAnalysed = master.FEA.NumberofAnalysis
numAnalysed = master.FEA.NumberOfAnalysis

return (statuses, numAnalysed)


def checkGenParameters(master):
header = master.Generate.Parameters_Name
parameters = master.Generate.Generated_Parameters
if parameters == None:
header = [""]
parameters = []

return (header, parameters)


def showGen(table, master, item):
global old
Expand All @@ -108,6 +103,52 @@ def showGen(table, master, item):
FreeCAD.setActiveDocument(docName)



def get_results_fc(doc, case):
import os
import femmesh.femmesh2mesh
import Mesh
file_path = doc.Topology.path
file = os.path.join(file_path, "topology_iterations", "file" + str(case).zfill(3))
result_state0 = f"{file}_state0"
result_state1 = f"{file}_state1"
# Hide all previous mesh objects
meshes = doc.findObjects('Mesh::Feature')
for mesh in meshes:
mesh.Visibility = False
for obj in doc.Topology.Group:
obj.Visibility = False
# If the file is already imported, open it
if doc.getObject(os.path.split(file)[1]):
doc.getObject(os.path.split(file)[1]).Visibility = True
else:
state = FreeCAD.ActiveDocument.addObject(
"App::DocumentObjectGroupPython", os.path.split(file)[1])
Fem.insert(f"{result_state0}.inp", doc.Name)
Fem.insert(f"{result_state1}.inp", doc.Name)
Gui.getDocument(doc).getObject(os.path.split(result_state0)[1]).ShapeColor = (1., 0., 0.)
Gui.getDocument(doc).getObject(os.path.split(result_state0)[1]).Transparency = 80
Gui.getDocument(doc).getObject(os.path.split(result_state0)[1]).LineWidth = 0.1
Gui.getDocument(doc).getObject(os.path.split(result_state1)[1]).ShapeColor = (0., 1., 0.)
state.addObject(doc.getObject(os.path.split(result_state0)[1]))
state.addObject(doc.getObject(os.path.split(result_state1)[1]))
femmesh_object=doc.getObject(os.path.split(result_state1)[1])
out_mesh = femmesh.femmesh2mesh.femmesh_2_mesh(femmesh_object.FemMesh)
mesh_filename = f"Smooth{case:03}"
Mesh.show(Mesh.Mesh(out_mesh), mesh_filename)
obj=doc.getObject(mesh_filename)
state.addObject(obj)
obj.Mesh.smooth("Laplace", 10, 0.6307, 0.0424)
doc.Topology.addObject(state)
state1 = doc.getObject(os.path.split(result_state0)[1])
state2 = doc.getObject(os.path.split(result_state1)[1])

if state1 is not None:
state1.Visibility = False

if state2 is not None:
state2.Visibility = False

class GenTableModel(PySide.QtCore.QAbstractTableModel):
def __init__(self, parent, itemList, header, colours=None, score=None, *args):

Expand Down Expand Up @@ -174,4 +215,4 @@ def sort(self, col, order):

if order != PySide.QtCore.Qt.DescendingOrder:
self.itemList.reverse()
self.layoutChanged.emit()
self.layoutChanged.emit()
30 changes: 17 additions & 13 deletions fembygen/FEA.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import FreeCAD
import FreeCADGui
import FemGui
import os.path
import os
from fembygen import Common
import shutil
import os
Expand All @@ -19,7 +19,7 @@ def makeFEA():
except:
try:
obj = FreeCAD.ActiveDocument.addObject("Part::FeaturePython", "FEA")
FreeCAD.ActiveDocument.Generative_Design.addObject(obj)
FreeCAD.ActiveDocument.GenerativeDesign.addObject(obj)
except:
return None
FEA(obj)
Expand All @@ -41,7 +41,7 @@ def initProperties(self, obj):
try:
obj.addProperty("App::PropertyPythonObject", "Status", "Base",
"Analysis Status")
obj.addProperty("App::PropertyInteger", "NumberofAnalysis", "Base",
obj.addProperty("App::PropertyInteger", "NumberOfAnalysis", "Base",
"Number of Analysis")
obj.addProperty("App::PropertyInteger", "NumberOfLoadCase", "Base",
"Number of Load Cases")
Expand All @@ -53,7 +53,7 @@ class FEACommand():
"""Perform FEA on generated parts"""

def GetResources(self):
return {'Pixmap': os.path.join(FreeCAD.getUserAppDataDir() + 'Mod/FEMbyGEN/fembygen/FEA.svg'), # the name of a svg file available in the resources
return {'Pixmap': os.path.join(FreeCAD.getUserAppDataDir() + 'Mod/FEMbyGEN/fembygen/icons/FEA.svg'), # the name of a svg file available in the resources
'Accel': "Shift+A", # a default shortcut (optional)
'MenuText': "FEA Generations",
'ToolTip': "Perform FEA on generated parts"}
Expand Down Expand Up @@ -82,7 +82,7 @@ def __init__(self, object):
self.obj = object
self.doc = object.Object.Document
# this will create a Qt widget from our ui file
guiPath = FreeCAD.getUserAppDataDir() + "Mod/FEMbyGEN/fembygen/PerformFEA.ui"
guiPath = FreeCAD.getUserAppDataDir() + "Mod/FEMbyGEN/fembygen/ui/PerformFEA.ui"
self.form = FreeCADGui.PySideUic.loadUi(guiPath)
self.workingDir = '/'.join(
object.Object.Document.FileName.split('/')[0:-1])
Expand Down Expand Up @@ -120,7 +120,7 @@ def deleteGenerations(self):
except:
pass
self.doc.FEA.Status = []
self.doc.FEA.NumberofAnalysis = 0
self.doc.FEA.NumberOfAnalysis = 0
self.doc.FEA.NumberOfLoadCase = 0
self.updateAnalysisTable()

Expand All @@ -141,7 +141,7 @@ def FEAGenerations(self):
lc += 1
FemGui.setActiveAnalysis(obj)
analysisfolder = os.path.join(
self.workingDir + f"/Gen{i+1}/loadCase{lc}")
self.workingDir + f"/Gen{i+1}/loadCase_{lc}")
os.mkdir(analysisfolder)
# Run FEA solver on generation
self.performFEA(Gen_Doc, obj, analysisfolder)
Expand All @@ -158,7 +158,7 @@ def FEAGenerations(self):

(statuses, numAnalysed, numLoadCase) = Common.searchAnalysed(self.doc)
self.doc.FEA.Status = statuses
self.doc.FEA.NumberofAnalysis = numAnalysed
self.doc.FEA.NumberOfAnalysis = numAnalysed
self.doc.FEA.NumberOfLoadCase = numLoadCase
FreeCAD.setActiveDocument(self.doc.Name)
self.doc.save()
Expand Down Expand Up @@ -232,8 +232,14 @@ def performFEA(self, doc, Analysis, Directory):
# run the analysis step by step

# , solver=doc.SolverCcxTools)
fea = ccxtools.FemToolsCcx(analysis=Analysis)
# analysisDir=self.workingDir+f"/Gen{GenerationNumber}"
try:
fea=ccxtools.FemToolsCcx(Analysis)
except:
print("adding")
import ObjectsFem
Analysis.addObject(ObjectsFem.makeSolverCalculixCcxTools(doc))
fea=ccxtools.FemToolsCcx(Analysis)

fea.setup_working_dir(Directory)
fea.update_objects()
fea.setup_ccx()
Expand All @@ -247,8 +253,6 @@ def performFEA(self, doc, Analysis, Directory):
else:
FreeCAD.Console.PrintError(
"Houston, we have a problem! {}\n".format(message)) # in report view
print("Houston, we have a problem! {}\n".format(
message)) # in python console

# save FEA results
doc.save()
Expand All @@ -273,7 +277,7 @@ def __init__(self, vobj):

def getIcon(self):
icon_path = os.path.join(
FreeCAD.getUserAppDataDir() + 'Mod/FEMbyGEN/fembygen/FEA.svg')
FreeCAD.getUserAppDataDir() + 'Mod/FEMbyGEN/fembygen/icons/FEA.svg')
return icon_path

def attach(self, vobj):
Expand Down
Loading

0 comments on commit 3225d01

Please sign in to comment.