Add PDDL, 3D-assets & SDF-URDF generator from Blender Scene Config
This commit is contained in:
parent
b77687ea14
commit
e305d486f2
41 changed files with 2793 additions and 664 deletions
|
@ -1,6 +1,4 @@
|
|||
{
|
||||
"doc": "/home/idontsudo/framework/asp/out/disk_and_axis_n.FCStd",
|
||||
"out": "/home/idontsudo/framework/asp/out",
|
||||
"resultURL": "http://localhost:3002/assembly/save/out",
|
||||
"projectId": "cubes"
|
||||
}
|
||||
"cadFilePath": "/Users/idontsudo/Desktop/asp-example/disk_and_axis_n.FCStd",
|
||||
"outPath": "/Users/idontsudo/Desktop/asp-example/"
|
||||
}
|
||||
|
|
28
cad_generation/helper/file_system_repository.py
Normal file
28
cad_generation/helper/file_system_repository.py
Normal file
|
@ -0,0 +1,28 @@
|
|||
import os
|
||||
import json
|
||||
import shutil
|
||||
|
||||
|
||||
class FileSystemRepository:
|
||||
def readJSON(path: str):
|
||||
return json.loads((open(path)).read())
|
||||
|
||||
def recursiveDeleteFolder(path: str):
|
||||
shutil.rmtree(path)
|
||||
pass
|
||||
|
||||
def deletingOldAndCreatingNewFolder(path: str):
|
||||
if FileSystemRepository.isExistsPath(path):
|
||||
FileSystemRepository.recursiveDeleteFolder(path)
|
||||
os.makedirs(path)
|
||||
pass
|
||||
|
||||
def isExistsPath(path: str):
|
||||
return os.path.exists(path)
|
||||
|
||||
def writeFile(data, filePath, fileName):
|
||||
file_to_open = filePath + fileName
|
||||
|
||||
f = open(file_to_open, "w", encoding="utf-8", errors="ignore")
|
||||
f.write(data)
|
||||
f.close()
|
|
@ -1,15 +0,0 @@
|
|||
import os
|
||||
import json
|
||||
|
||||
|
||||
class FS:
|
||||
def readJSON(path: str):
|
||||
return json.loads((open(path)).read())
|
||||
|
||||
def writeFile(data, filePath, fileName):
|
||||
file_to_open = filePath + fileName
|
||||
|
||||
f = open(file_to_open, 'w', encoding='utf-8',
|
||||
errors='ignore')
|
||||
f.write(data)
|
||||
f.close()
|
|
@ -1,19 +1,25 @@
|
|||
import requests
|
||||
import FreeCAD as App
|
||||
from helper.fs import FS
|
||||
from scenarios.robossembler_freecad_export_scenario import RobossemblerFreeCadExportScenario
|
||||
import shutil
|
||||
import os
|
||||
from helper.file_system_repository import FileSystemRepository
|
||||
from scenarios.robossembler_freecad_export_scenari import (
|
||||
RobossemblerFreeCadExportScenari,
|
||||
)
|
||||
|
||||
|
||||
import FreeCADGui as Gui
|
||||
|
||||
# obj.Support[0][0].Label
|
||||
# 'Hex_King'
|
||||
|
||||
import FreeCAD as App
|
||||
|
||||
|
||||
def main():
|
||||
env = FS.readJSON('./env.json')
|
||||
App.openDocument(env.get('doc'))
|
||||
RobossemblerFreeCadExportScenario().call(env.get('out'))
|
||||
# requests.post(url=env.get('resultURL'), files={'zip': open(env.get('out') + '/' + 'generation.zip', "rb"), 'id':env.get('projectId')})
|
||||
# os.remove('./generation.zip')
|
||||
env = FileSystemRepository.readJSON("./env.json")
|
||||
App.openDocument(env.get("cadFilePath"))
|
||||
RobossemblerFreeCadExportScenari.call(env.get("outPath"))
|
||||
App.closeDocument(App.ActiveDocument.Name)
|
||||
freecadQTWindow = Gui.getMainWindow()
|
||||
freecadQTWindow = Gui.getMainWindow()
|
||||
freecadQTWindow.close()
|
||||
|
||||
|
||||
main()
|
||||
|
|
|
@ -26,7 +26,28 @@ def to_class(c, x):
|
|||
|
||||
|
||||
class SdfGeometryModel:
|
||||
def __init__(self, name, ixx, ixy, ixz, iyy, izz, massSDF, posX, posY, posZ, eulerX, eulerY, eulerZ, iyz, stl, friction, centerMassX, centerMassY, centerMassZ,):
|
||||
def __init__(
|
||||
self,
|
||||
name,
|
||||
ixx,
|
||||
ixy,
|
||||
ixz,
|
||||
iyy,
|
||||
izz,
|
||||
massSDF,
|
||||
posX,
|
||||
posY,
|
||||
posZ,
|
||||
eulerX,
|
||||
eulerY,
|
||||
eulerZ,
|
||||
iyz,
|
||||
stl,
|
||||
friction,
|
||||
centerMassX,
|
||||
centerMassY,
|
||||
centerMassZ,
|
||||
):
|
||||
self.name = name
|
||||
self.ixx = ixx
|
||||
self.ixy = ixy
|
||||
|
@ -69,7 +90,27 @@ class SdfGeometryModel:
|
|||
centerMassX = from_union([from_str, from_none], obj.get("centerMassX"))
|
||||
centerMassY = from_union([from_str, from_none], obj.get("centerMassY"))
|
||||
centerMassZ = from_union([from_str, from_none], obj.get("centerMassZ"))
|
||||
return SdfGeometryModel(name, ixx, ixy, ixz, iyy, izz, massSDF, posX, posY, posZ, eulerX, eulerY, eulerZ, iyz, stl, friction, centerMassX, centerMassY, centerMassZ)
|
||||
return SdfGeometryModel(
|
||||
name,
|
||||
ixx,
|
||||
ixy,
|
||||
ixz,
|
||||
iyy,
|
||||
izz,
|
||||
massSDF,
|
||||
posX,
|
||||
posY,
|
||||
posZ,
|
||||
eulerX,
|
||||
eulerY,
|
||||
eulerZ,
|
||||
iyz,
|
||||
stl,
|
||||
friction,
|
||||
centerMassX,
|
||||
centerMassY,
|
||||
centerMassZ,
|
||||
)
|
||||
|
||||
def to_dict(self):
|
||||
result = {}
|
||||
|
@ -105,14 +146,13 @@ class SdfGeometryModel:
|
|||
result["stl"] = from_union([from_str, from_none], self.stl)
|
||||
if self.friction is not None:
|
||||
result["friction"] = from_union([from_str, from_none], self.eulerZ)
|
||||
|
||||
if self.centerMassX is not None:
|
||||
result['centerMassX'] = from_union([from_str, from_none], self.centerMassX)
|
||||
result["centerMassX"] = from_union([from_str, from_none], self.centerMassX)
|
||||
if self.centerMassY is not None:
|
||||
result['centerMassY'] = from_union([from_str, from_none], self.centerMassY)
|
||||
result["centerMassY"] = from_union([from_str, from_none], self.centerMassY)
|
||||
if self.centerMassZ is not None:
|
||||
result['centerMassZ'] = from_union([from_str, from_none], self.centerMassZ)
|
||||
result["centerMassZ"] = from_union([from_str, from_none], self.centerMassZ)
|
||||
return result
|
||||
|
||||
def toJSON(self) -> str:
|
||||
return str(self.to_dict()).replace('\'', '"')
|
||||
return str(self.to_dict()).replace("'", '"')
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
from usecases.export_assembly_them_all_usecase import ExportAssemblyThemAllUseCase
|
||||
import FreeCAD
|
||||
from usecases.export_usecase import EXPORT_TYPES, ExportUseCase
|
||||
from usecases.get_sdf_geometry_usecase import SdfGeometryUseCase
|
||||
from usecases.assembly_parse_usecase import AssemblyParseUseCase
|
||||
from model.files_generator import FolderGenerator
|
||||
from helper.file_system_repository import FileSystemRepository
|
||||
import os
|
||||
|
||||
|
||||
class RobossemblerFreeCadExportScenari:
|
||||
def call(path):
|
||||
directory = path
|
||||
|
||||
__objs__ = FreeCAD.ActiveDocument.RootObjects
|
||||
directoryExport = directory + "/"
|
||||
FileSystemRepository.deletingOldAndCreatingNewFolder(
|
||||
directoryExport + FolderGenerator.ASSETS.value
|
||||
)
|
||||
FileSystemRepository.deletingOldAndCreatingNewFolder(
|
||||
directoryExport + FolderGenerator.SDF.value,
|
||||
)
|
||||
|
||||
FileSystemRepository.deletingOldAndCreatingNewFolder(
|
||||
directoryExport
|
||||
+ FolderGenerator.SDF.value
|
||||
+ "/"
|
||||
+ FolderGenerator.MESHES.value
|
||||
)
|
||||
FileSystemRepository.deletingOldAndCreatingNewFolder(
|
||||
directoryExport + FolderGenerator.ASSEMBlY.value
|
||||
)
|
||||
f = open(directory + "/step-structure.json", "w")
|
||||
f.write(AssemblyParseUseCase().toJson())
|
||||
f.close()
|
||||
RobossemblerFreeCadExportScenari.geometry(directory)
|
||||
ExportAssemblyThemAllUseCase().call(directoryExport)
|
||||
|
||||
return True
|
||||
|
||||
def geometry(outPutsPath: str):
|
||||
exportUseCase = ExportUseCase.call(outPutsPath, EXPORT_TYPES.OBJ)
|
||||
|
||||
for el in SdfGeometryUseCase().call(exportUseCase):
|
||||
FileSystemRepository.writeFile(
|
||||
el.toJSON(),
|
||||
outPutsPath + FolderGenerator.ASSETS.value + "/",
|
||||
el.name + ".json",
|
||||
)
|
|
@ -1,52 +0,0 @@
|
|||
|
||||
from usecases.export_assembly_them_all_usecase import ExportAssemblyThemAllUseCase
|
||||
import FreeCAD
|
||||
from usecases.export_usecase import EXPORT_TYPES, ExportUseCase
|
||||
from usecases.get_sdf_geometry_usecase import SdfGeometryUseCase
|
||||
from usecases.assembly_parse_usecase import AssemblyParseUseCase
|
||||
from usecases.geometry_usecase import GeometryUseCase
|
||||
from model.geometry_part import GeometryPart
|
||||
from model.files_generator import FolderGenerator
|
||||
from helper.fs import FS
|
||||
import os
|
||||
import shutil
|
||||
|
||||
|
||||
class RobossemblerFreeCadExportScenario:
|
||||
|
||||
def call(self, path):
|
||||
|
||||
|
||||
directory = path + '/' + 'generation'
|
||||
if os.path.exists(directory):
|
||||
shutil.rmtree(directory)
|
||||
if not os.path.exists(directory):
|
||||
os.makedirs(directory)
|
||||
|
||||
__objs__ = FreeCAD.ActiveDocument.RootObjects
|
||||
directoryExport = directory + '/'
|
||||
os.makedirs(directoryExport + FolderGenerator.ASSETS.value)
|
||||
|
||||
os.makedirs(directoryExport + FolderGenerator.SDF.value)
|
||||
os.makedirs(directoryExport + FolderGenerator.SDF.value + '/' + FolderGenerator.MESHES.value)
|
||||
os.makedirs(directoryExport + FolderGenerator.ASSEMBlY.value)
|
||||
f = open(directory + "/step-structure.json", "w")
|
||||
f.write(AssemblyParseUseCase().toJson())
|
||||
f.close()
|
||||
self.geometry(directory)
|
||||
ExportAssemblyThemAllUseCase().call(directoryExport)
|
||||
|
||||
# shutil.make_archive(directory, 'zip', directory)
|
||||
|
||||
# shutil.rmtree(directory)
|
||||
return True
|
||||
|
||||
def geometry(self, outPutsPath: str):
|
||||
exportUseCase = ExportUseCase.call(outPutsPath,EXPORT_TYPES.OBJ)
|
||||
for el in SdfGeometryUseCase().call(exportUseCase):
|
||||
FS.writeFile(el.toJSON(), outPutsPath + '/' + FolderGenerator.ASSETS.value + '/', el.name + '.json',)
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,11 +1,9 @@
|
|||
|
||||
|
||||
from typing import List
|
||||
import FreeCAD as App
|
||||
import Part
|
||||
from model.join_mesh_model import JoinMeshModel
|
||||
from model.mesh_part_model import MeshPartModel
|
||||
from helper.fs import FS
|
||||
from helper.file_system_repository import FileSystemRepository
|
||||
from helper.is_solid import is_object_solid
|
||||
from model.simple_copy_part_model import SimpleCopyPartModel
|
||||
from model.files_generator import FolderGenerator
|
||||
|
@ -15,78 +13,106 @@ import json
|
|||
|
||||
|
||||
class ExportAssemblyThemAllUseCase:
|
||||
|
||||
def call(self, path):
|
||||
assembly = AssemblyParseUseCase().getAsm()
|
||||
asmStructure = {}
|
||||
inc = 0
|
||||
for el in assembly:
|
||||
if (inc != 0):
|
||||
asmStructure[inc] = {
|
||||
"child": el,
|
||||
"parents": assembly[0:inc]
|
||||
}
|
||||
if inc != 0:
|
||||
asmStructure[inc] = {"child": el, "parents": assembly[0:inc]}
|
||||
inc += 1
|
||||
objectsFreeCad = App.ActiveDocument.Objects
|
||||
asmSolids = {}
|
||||
for k, v in asmStructure.items():
|
||||
assemblyParentList = v['parents']
|
||||
assemblyChild = v['child']
|
||||
assemblyParentList = v["parents"]
|
||||
assemblyChild = v["child"]
|
||||
for el in assemblyParentList:
|
||||
for solid in objectsFreeCad:
|
||||
if (el == solid.Label):
|
||||
if (asmSolids.get(k) is None):
|
||||
if el == solid.Label:
|
||||
if asmSolids.get(k) is None:
|
||||
asmSolids[k] = {
|
||||
"parents": [],
|
||||
"child": list(
|
||||
filter(
|
||||
lambda x: x.Label == assemblyChild,
|
||||
objectsFreeCad,
|
||||
)
|
||||
)[0],
|
||||
}
|
||||
|
||||
asmSolids[k] = {'parents': [], 'child': list(
|
||||
filter(lambda x: x.Label == assemblyChild, objectsFreeCad))[0]}
|
||||
|
||||
asmSolids[k]['parents'].append(solid)
|
||||
asmSolids[k]["parents"].append(solid)
|
||||
|
||||
inc = 0
|
||||
for k, v in asmSolids.items():
|
||||
geometry = {"0": [], "1": []}
|
||||
if (k != 0):
|
||||
if k != 0:
|
||||
App.activeDocument().addObject("Part::Compound", "Compound")
|
||||
|
||||
copyLinks = list(
|
||||
map(lambda el: SimpleCopyPartModel(el), v['parents']))
|
||||
copyLinks = list(map(lambda el: SimpleCopyPartModel(el), v["parents"]))
|
||||
|
||||
if copyLinks != None:
|
||||
App.activeDocument().Compound.Links = list(
|
||||
map(lambda el: el.getPart(), copyLinks))
|
||||
map(lambda el: el.getPart(), copyLinks)
|
||||
)
|
||||
|
||||
object = App.activeDocument().getObject('Compound')
|
||||
object = App.activeDocument().getObject("Compound")
|
||||
boundBox = object.Shape.BoundBox
|
||||
geometry['0'].append(boundBox.XMax)
|
||||
geometry['0'].append(boundBox.YMax)
|
||||
geometry['0'].append(boundBox.ZMax)
|
||||
geometry["0"].append(boundBox.XMax)
|
||||
geometry["0"].append(boundBox.YMax)
|
||||
geometry["0"].append(boundBox.ZMax)
|
||||
|
||||
os.makedirs(
|
||||
path + FolderGenerator.ASSEMBlY.value + '/' + '0000' + str(k))
|
||||
boundBoxChild = v['child'].Shape.BoundBox
|
||||
geometry['1'].append(boundBoxChild.XMax)
|
||||
geometry['1'].append(boundBoxChild.YMax)
|
||||
geometry['1'].append(boundBoxChild.ZMax)
|
||||
path + FolderGenerator.ASSEMBlY.value + "/" + "0000" + str(k)
|
||||
)
|
||||
boundBoxChild = v["child"].Shape.BoundBox
|
||||
geometry["1"].append(boundBoxChild.XMax)
|
||||
geometry["1"].append(boundBoxChild.YMax)
|
||||
geometry["1"].append(boundBoxChild.ZMax)
|
||||
meshParents = []
|
||||
|
||||
for el in v['parents']:
|
||||
|
||||
for el in v["parents"]:
|
||||
meshParents.append(MeshPartModel(el))
|
||||
joinMesh = JoinMeshModel(meshParents)
|
||||
for el in meshParents:
|
||||
el.remove()
|
||||
import importOBJ
|
||||
importOBJ.export(joinMesh.mesh, path + FolderGenerator.ASSEMBlY.value +
|
||||
'/' + '0000' + str(k) + '/' + str(1) + '.obj')
|
||||
|
||||
importOBJ.export(
|
||||
joinMesh.mesh,
|
||||
path
|
||||
+ FolderGenerator.ASSEMBlY.value
|
||||
+ "/"
|
||||
+ "0000"
|
||||
+ str(k)
|
||||
+ "/"
|
||||
+ str(1)
|
||||
+ ".obj",
|
||||
)
|
||||
joinMesh.remove()
|
||||
importOBJ.export(v['child'], path + FolderGenerator.ASSEMBlY.value +
|
||||
'/' + '0000' + str(k) + '/' + str(0) + '.obj')
|
||||
FS.writeFile(json.dumps(geometry), path + FolderGenerator.ASSEMBlY.value +
|
||||
'/' + '0000' + str(k) + '/', 'translation.json')
|
||||
importOBJ.export(
|
||||
v["child"],
|
||||
path
|
||||
+ FolderGenerator.ASSEMBlY.value
|
||||
+ "/"
|
||||
+ "0000"
|
||||
+ str(k)
|
||||
+ "/"
|
||||
+ str(0)
|
||||
+ ".obj",
|
||||
)
|
||||
FileSystemRepository.writeFile(
|
||||
json.dumps(geometry),
|
||||
path
|
||||
+ FolderGenerator.ASSEMBlY.value
|
||||
+ "/"
|
||||
+ "0000"
|
||||
+ str(k)
|
||||
+ "/",
|
||||
"translation.json",
|
||||
)
|
||||
|
||||
App.ActiveDocument.removeObject("Compound")
|
||||
for el in copyLinks:
|
||||
el.remove()
|
||||
App.activeDocument().recompute()
|
||||
inc += 1
|
||||
|
||||
|
||||
|
|
|
@ -4,33 +4,54 @@ import FreeCAD as App
|
|||
from model.files_generator import FolderGenerator
|
||||
from helper.is_solid import is_object_solid
|
||||
from enum import Enum
|
||||
|
||||
|
||||
|
||||
class EXPORT_TYPES(Enum):
|
||||
STL = 'STL'
|
||||
DAO = 'DAO'
|
||||
OBJ = 'OBJ'
|
||||
|
||||
STL = "STL"
|
||||
DAO = "DAO"
|
||||
OBJ = "OBJ"
|
||||
|
||||
|
||||
class ExportUseCase:
|
||||
def call(path: str, type: EXPORT_TYPES):
|
||||
meshes = {}
|
||||
for el in App.ActiveDocument.Objects:
|
||||
if (is_object_solid(el)):
|
||||
if is_object_solid(el):
|
||||
match type.value:
|
||||
case EXPORT_TYPES.STL.value:
|
||||
Mesh.export([el], path + '/' + FolderGenerator.SDF.value +
|
||||
'/' + FolderGenerator.MESHES.value + '/' + el.Label + '.stl')
|
||||
meshes[el.Label] = '/' + FolderGenerator.MESHES.value + \
|
||||
'/' + el.Label + '.stl'
|
||||
Mesh.export(
|
||||
[el],
|
||||
path
|
||||
+ "/"
|
||||
+ FolderGenerator.SDF.value
|
||||
+ "/"
|
||||
+ FolderGenerator.MESHES.value
|
||||
+ "/"
|
||||
+ el.Label
|
||||
+ ".stl",
|
||||
)
|
||||
meshes[el.Label] = (
|
||||
"/" + FolderGenerator.MESHES.value + "/" + el.Label + ".stl"
|
||||
)
|
||||
|
||||
# case EXPORT_TYPES.DAO.value:
|
||||
# importDAE.export([el], path + '/' + FolderGenerator.SDF.value +
|
||||
# '/' + FolderGenerator.MESHES.value + '/' + el.Label + '.dae')
|
||||
case EXPORT_TYPES.OBJ.value:
|
||||
import importOBJ
|
||||
importOBJ.export([el], path + '/' + FolderGenerator.SDF.value +
|
||||
'/' + FolderGenerator.MESHES.value + '/' + el.Label + '.obj')
|
||||
meshes[el.Label] = '/' + FolderGenerator.MESHES.value + \
|
||||
'/' + el.Label + '.obj'
|
||||
print(300)
|
||||
|
||||
importOBJ.export(
|
||||
[el],
|
||||
path
|
||||
+ "/"
|
||||
+ FolderGenerator.SDF.value
|
||||
+ "/"
|
||||
+ FolderGenerator.MESHES.value
|
||||
+ "/"
|
||||
+ el.Label
|
||||
+ ".obj",
|
||||
)
|
||||
meshes[el.Label] = (
|
||||
"/" + FolderGenerator.MESHES.value + "/" + el.Label + ".obj"
|
||||
)
|
||||
return meshes
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue