Skip to content

Commit 2f7aa7e

Browse files
authored
Merge pull request #12 from OpenSEMBA/feature/create-area-file
New file with listed áreas
2 parents 1a38fb2 + 759ce83 commit 2f7aa7e

9 files changed

Lines changed: 455 additions & 5 deletions

File tree

src/AreaExporterService.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import json
2+
import gmsh
3+
from typing import Dict, List
4+
import numpy as np
5+
class AreaExporterService:
6+
_EMPTY_NAME_CASE = ""
7+
computedAreas:Dict[str,List]
8+
geometry: Dict
9+
def __init__(self):
10+
self.computedAreas = {
11+
"geometries": []
12+
}
13+
14+
def addComputedArea(self, geometry:str, area:float):
15+
geometry:Dict ={
16+
"geometry": geometry,
17+
"area": area,
18+
}
19+
self.computedAreas['geometries'].append(geometry)
20+
21+
def addPhysicalModelOfDimension(self, dimension=2):
22+
physicalGroups = gmsh.model.getPhysicalGroups(dimension)
23+
for physicalGroup in physicalGroups:
24+
entityTags = gmsh.model.getEntitiesForPhysicalGroup(*physicalGroup)
25+
geometryName = gmsh.model.getPhysicalName(*physicalGroup)
26+
for tag in entityTags:
27+
if dimension == 1:
28+
rad = gmsh.model.occ.getMass(dimension, tag) / (2*np.pi)
29+
area = rad*rad*np.pi
30+
if dimension == 2:
31+
area = gmsh.model.occ.getMass(dimension, tag)
32+
if geometryName != AreaExporterService._EMPTY_NAME_CASE:
33+
self.addComputedArea(geometryName, area)
34+
35+
def exportToJson(self, exportFileName:str):
36+
with open(exportFileName + ".areas.json", 'w') as f:
37+
json.dump(self.computedAreas, f, indent=3)

src/mesher.py

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
from typing import Tuple
22
import gmsh
3-
from collections import defaultdict
4-
from itertools import chain
53
from pathlib import Path
6-
from typing import Any, Tuple, List, Dict
4+
from typing import Dict
5+
6+
from src.AreaExporterService import AreaExporterService
77
from .ShapesClassification import ShapesClassification
88

99
class Mesher():
@@ -29,8 +29,8 @@ def runFromInput(self, inputFile, runGui=False):
2929
caseName = Path(inputFile).stem
3030

3131
gmsh.initialize()
32-
self.meshFromStep(inputFile, caseName, self.DEFAULT_MESHING_OPTIONS)
33-
32+
self.meshFromStep(inputFile, caseName, self.DEFAULT_MESHING_OPTIONS)
33+
self.exportGeometryAreas(caseName)
3434
gmsh.write(caseName + '.msh')
3535
gmsh.write(caseName + '.vtk')
3636
if runGui:
@@ -66,6 +66,13 @@ def meshFromStep(self, inputFile: str, caseName: str, meshingOptions=None):
6666

6767
gmsh.model.mesh.generate(2)
6868

69+
def exportGeometryAreas(self, caseName:str):
70+
exporter = AreaExporterService()
71+
exporter.addPhysicalModelOfDimension(dimension=2)
72+
exporter.addPhysicalModelOfDimension(dimension=1)
73+
exporter.exportToJson(caseName)
74+
75+
6976
def buildPhysicalModel(self, pecBoundaries, dielectrics, openRegion, vacuumDomain):
7077
self._addPhysicalGroup("Conductor_", pecBoundaries, dimensionTag=1)
7178
self._addPhysicalGroup("OpenBoundary_", openRegion, dimensionTag=1)
@@ -81,12 +88,15 @@ def buildPhysicalModel(self, pecBoundaries, dielectrics, openRegion, vacuumDomai
8188

8289
entsNotInPG = [x for x in allEnts if x not in entsInPG]
8390
gmsh.model.remove_entities(entsNotInPG, recursive=False)
91+
gmsh.model.occ.synchronize()
92+
8493

8594
def _addPhysicalGroup(self, physicalGroupName:str, objsDict:Dict, dimensionTag=1):
8695
for num, objs in objsDict.items():
8796
name = physicalGroupName + str(num)
8897
tags = [x[1] for x in objs]
8998
gmsh.model.addPhysicalGroup(dimensionTag, tags, name=name)
99+
90100

91101
@staticmethod
92102
def getPhysicalGroupWithName(name: str):

test/test_AreaExporterService.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
from typing import List
2+
import unittest
3+
import os
4+
import numpy as np
5+
import gmsh
6+
from src.mesher import Mesher
7+
from src.AreaExporterService import AreaExporterService
8+
class testAreaExporterService(unittest.TestCase):
9+
@staticmethod
10+
def sumAreasFromList(areas:List[float]):
11+
total:float = 0
12+
for area in areas:
13+
total += area
14+
return total
15+
16+
@classmethod
17+
def setUpClass(cls):
18+
cls.dirPath = os.path.dirname(os.path.realpath(__file__)) + '/'
19+
cls.testdataPath = cls.dirPath + '/../testData/'
20+
21+
def setUp(self):
22+
gmsh.initialize()
23+
24+
def tearDown(self):
25+
gmsh.finalize()
26+
def inputFileFromCaseName(self, caseName):
27+
return self.testdataPath + caseName + '/' + caseName + ".step"
28+
29+
def testAreaExporterReturnsTrueValues(self):
30+
caseName = 'five_wires'
31+
Mesher().meshFromStep(self.inputFileFromCaseName(caseName), caseName)
32+
areaExporter = AreaExporterService()
33+
areaExporter.addPhysicalModelOfDimension(dimension=1)
34+
areaExporter.addPhysicalModelOfDimension(dimension=2)
35+
geometries = areaExporter.computedAreas['geometries']
36+
37+
internalElements = []
38+
for geometry in geometries:
39+
if geometry['geometry'] == "Conductor_0":
40+
totalArea = geometry['area']
41+
else:
42+
internalElements.append(geometry['area'])
43+
areaElements = self.sumAreasFromList(internalElements)
44+
45+
self.assertAlmostEqual(totalArea, areaElements)
15.5 KB
Binary file not shown.
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
ISO-10303-21;
2+
HEADER;
3+
FILE_DESCRIPTION(('FreeCAD Model'),'2;1');
4+
FILE_NAME('Open CASCADE Shape Model','2025-05-12T12:26:04',(''),(''),
5+
'Open CASCADE STEP processor 7.6','FreeCAD','Unknown');
6+
FILE_SCHEMA(('AUTOMOTIVE_DESIGN { 1 0 10303 214 1 1 1 1 }'));
7+
ENDSEC;
8+
DATA;
9+
#1 = APPLICATION_PROTOCOL_DEFINITION('international standard',
10+
'automotive_design',2000,#2);
11+
#2 = APPLICATION_CONTEXT(
12+
'core data for automotive mechanical design processes');
13+
#3 = SHAPE_DEFINITION_REPRESENTATION(#4,#10);
14+
#4 = PRODUCT_DEFINITION_SHAPE('','',#5);
15+
#5 = PRODUCT_DEFINITION('design','',#6,#9);
16+
#6 = PRODUCT_DEFINITION_FORMATION('','',#7);
17+
#7 = PRODUCT('Unnamed','Unnamed','',(#8));
18+
#8 = PRODUCT_CONTEXT('',#2,'mechanical');
19+
#9 = PRODUCT_DEFINITION_CONTEXT('part definition',#2,'design');
20+
#10 = SHAPE_REPRESENTATION('',(#11,#15,#19),#23);
21+
#11 = AXIS2_PLACEMENT_3D('',#12,#13,#14);
22+
#12 = CARTESIAN_POINT('',(0.,0.,0.));
23+
#13 = DIRECTION('',(0.,0.,1.));
24+
#14 = DIRECTION('',(1.,0.,-0.));
25+
#15 = AXIS2_PLACEMENT_3D('',#16,#17,#18);
26+
#16 = CARTESIAN_POINT('',(0.,0.,0.));
27+
#17 = DIRECTION('',(0.,0.,1.));
28+
#18 = DIRECTION('',(1.,0.,0.));
29+
#19 = AXIS2_PLACEMENT_3D('',#20,#21,#22);
30+
#20 = CARTESIAN_POINT('',(0.,0.,0.));
31+
#21 = DIRECTION('',(0.,0.,1.));
32+
#22 = DIRECTION('',(1.,0.,0.));
33+
#23 = ( GEOMETRIC_REPRESENTATION_CONTEXT(3)
34+
GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT((#27)) GLOBAL_UNIT_ASSIGNED_CONTEXT(
35+
(#24,#25,#26)) REPRESENTATION_CONTEXT('Context #1',
36+
'3D Context with UNIT and UNCERTAINTY') );
37+
#24 = ( LENGTH_UNIT() NAMED_UNIT(*) SI_UNIT(.MILLI.,.METRE.) );
38+
#25 = ( NAMED_UNIT(*) PLANE_ANGLE_UNIT() SI_UNIT($,.RADIAN.) );
39+
#26 = ( NAMED_UNIT(*) SI_UNIT($,.STERADIAN.) SOLID_ANGLE_UNIT() );
40+
#27 = UNCERTAINTY_MEASURE_WITH_UNIT(LENGTH_MEASURE(1.E-07),#24,
41+
'distance_accuracy_value','confusion accuracy');
42+
#28 = PRODUCT_RELATED_PRODUCT_CATEGORY('part',$,(#7));
43+
#29 = SHAPE_DEFINITION_REPRESENTATION(#30,#36);
44+
#30 = PRODUCT_DEFINITION_SHAPE('','',#31);
45+
#31 = PRODUCT_DEFINITION('design','',#32,#35);
46+
#32 = PRODUCT_DEFINITION_FORMATION('','',#33);
47+
#33 = PRODUCT('Conductor_1','Conductor_1','',(#34));
48+
#34 = PRODUCT_CONTEXT('',#2,'mechanical');
49+
#35 = PRODUCT_DEFINITION_CONTEXT('part definition',#2,'design');
50+
#36 = MANIFOLD_SURFACE_SHAPE_REPRESENTATION('',(#11,#37),#56);
51+
#37 = SHELL_BASED_SURFACE_MODEL('',(#38));
52+
#38 = OPEN_SHELL('',(#39));
53+
#39 = ADVANCED_FACE('',(#40),#51,.T.);
54+
#40 = FACE_BOUND('',#41,.T.);
55+
#41 = EDGE_LOOP('',(#42));
56+
#42 = ORIENTED_EDGE('',*,*,#43,.T.);
57+
#43 = EDGE_CURVE('',#44,#44,#46,.T.);
58+
#44 = VERTEX_POINT('',#45);
59+
#45 = CARTESIAN_POINT('',(10.,0.,0.));
60+
#46 = CIRCLE('',#47,10.);
61+
#47 = AXIS2_PLACEMENT_3D('',#48,#49,#50);
62+
#48 = CARTESIAN_POINT('',(0.,0.,0.));
63+
#49 = DIRECTION('',(0.,0.,1.));
64+
#50 = DIRECTION('',(1.,0.,-0.));
65+
#51 = PLANE('',#52);
66+
#52 = AXIS2_PLACEMENT_3D('',#53,#54,#55);
67+
#53 = CARTESIAN_POINT('',(-5.469760530158E-16,1.387604533E-16,0.));
68+
#54 = DIRECTION('',(0.,0.,1.));
69+
#55 = DIRECTION('',(1.,0.,-0.));
70+
#56 = ( GEOMETRIC_REPRESENTATION_CONTEXT(3)
71+
GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT((#60)) GLOBAL_UNIT_ASSIGNED_CONTEXT(
72+
(#57,#58,#59)) REPRESENTATION_CONTEXT('Context #1',
73+
'3D Context with UNIT and UNCERTAINTY') );
74+
#57 = ( LENGTH_UNIT() NAMED_UNIT(*) SI_UNIT(.MILLI.,.METRE.) );
75+
#58 = ( NAMED_UNIT(*) PLANE_ANGLE_UNIT() SI_UNIT($,.RADIAN.) );
76+
#59 = ( NAMED_UNIT(*) SI_UNIT($,.STERADIAN.) SOLID_ANGLE_UNIT() );
77+
#60 = UNCERTAINTY_MEASURE_WITH_UNIT(LENGTH_MEASURE(1.E-07),#57,
78+
'distance_accuracy_value','confusion accuracy');
79+
#61 = CONTEXT_DEPENDENT_SHAPE_REPRESENTATION(#62,#64);
80+
#62 = ( REPRESENTATION_RELATIONSHIP('','',#36,#10)
81+
REPRESENTATION_RELATIONSHIP_WITH_TRANSFORMATION(#63)
82+
SHAPE_REPRESENTATION_RELATIONSHIP() );
83+
#63 = ITEM_DEFINED_TRANSFORMATION('','',#11,#15);
84+
#64 = PRODUCT_DEFINITION_SHAPE('Placement','Placement of an item',#65);
85+
#65 = NEXT_ASSEMBLY_USAGE_OCCURRENCE('1','Conductor_1','',#5,#31,$);
86+
#66 = PRODUCT_RELATED_PRODUCT_CATEGORY('part',$,(#33));
87+
#67 = SHAPE_DEFINITION_REPRESENTATION(#68,#74);
88+
#68 = PRODUCT_DEFINITION_SHAPE('','',#69);
89+
#69 = PRODUCT_DEFINITION('design','',#70,#73);
90+
#70 = PRODUCT_DEFINITION_FORMATION('','',#71);
91+
#71 = PRODUCT('Conductor_0','Conductor_0','',(#72));
92+
#72 = PRODUCT_CONTEXT('',#2,'mechanical');
93+
#73 = PRODUCT_DEFINITION_CONTEXT('part definition',#2,'design');
94+
#74 = GEOMETRICALLY_BOUNDED_WIREFRAME_SHAPE_REPRESENTATION('',(#11,#75),
95+
#84);
96+
#75 = GEOMETRIC_CURVE_SET('',(#76));
97+
#76 = TRIMMED_CURVE('',#77,(#82,PARAMETER_VALUE(0.)),(#83,
98+
PARAMETER_VALUE(6.28318530718)),.T.,.PARAMETER.);
99+
#77 = CIRCLE('',#78,50.);
100+
#78 = AXIS2_PLACEMENT_3D('',#79,#80,#81);
101+
#79 = CARTESIAN_POINT('',(0.,0.,0.));
102+
#80 = DIRECTION('',(0.,0.,1.));
103+
#81 = DIRECTION('',(1.,0.,-0.));
104+
#82 = CARTESIAN_POINT('',(50.,0.,0.));
105+
#83 = CARTESIAN_POINT('',(50.,0.,0.));
106+
#84 = ( GEOMETRIC_REPRESENTATION_CONTEXT(3)
107+
GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT((#88)) GLOBAL_UNIT_ASSIGNED_CONTEXT(
108+
(#85,#86,#87)) REPRESENTATION_CONTEXT('Context #1',
109+
'3D Context with UNIT and UNCERTAINTY') );
110+
#85 = ( LENGTH_UNIT() NAMED_UNIT(*) SI_UNIT(.MILLI.,.METRE.) );
111+
#86 = ( NAMED_UNIT(*) PLANE_ANGLE_UNIT() SI_UNIT($,.RADIAN.) );
112+
#87 = ( NAMED_UNIT(*) SI_UNIT($,.STERADIAN.) SOLID_ANGLE_UNIT() );
113+
#88 = UNCERTAINTY_MEASURE_WITH_UNIT(LENGTH_MEASURE(1.E-07),#85,
114+
'distance_accuracy_value','confusion accuracy');
115+
#89 = CONTEXT_DEPENDENT_SHAPE_REPRESENTATION(#90,#92);
116+
#90 = ( REPRESENTATION_RELATIONSHIP('','',#74,#10)
117+
REPRESENTATION_RELATIONSHIP_WITH_TRANSFORMATION(#91)
118+
SHAPE_REPRESENTATION_RELATIONSHIP() );
119+
#91 = ITEM_DEFINED_TRANSFORMATION('','',#11,#19);
120+
#92 = PRODUCT_DEFINITION_SHAPE('Placement','Placement of an item',#93);
121+
#93 = NEXT_ASSEMBLY_USAGE_OCCURRENCE('2','Conductor_0','',#5,#69,$);
122+
#94 = PRODUCT_RELATED_PRODUCT_CATEGORY('part',$,(#71));
123+
#95 = MECHANICAL_DESIGN_GEOMETRIC_PRESENTATION_REPRESENTATION('',(#96),
124+
#84);
125+
#96 = STYLED_ITEM('color',(#97),#75);
126+
#97 = PRESENTATION_STYLE_ASSIGNMENT((#98,#104));
127+
#98 = SURFACE_STYLE_USAGE(.BOTH.,#99);
128+
#99 = SURFACE_SIDE_STYLE('',(#100));
129+
#100 = SURFACE_STYLE_FILL_AREA(#101);
130+
#101 = FILL_AREA_STYLE('',(#102));
131+
#102 = FILL_AREA_STYLE_COLOUR('',#103);
132+
#103 = COLOUR_RGB('',0.800000010877,0.800000010877,0.800000010877);
133+
#104 = CURVE_STYLE('',#105,POSITIVE_LENGTH_MEASURE(0.1),#106);
134+
#105 = DRAUGHTING_PRE_DEFINED_CURVE_FONT('continuous');
135+
#106 = COLOUR_RGB('',9.803921802644E-02,9.803921802644E-02,
136+
9.803921802644E-02);
137+
#107 = MECHANICAL_DESIGN_GEOMETRIC_PRESENTATION_REPRESENTATION('',(#108)
138+
,#56);
139+
#108 = STYLED_ITEM('color',(#109),#39);
140+
#109 = PRESENTATION_STYLE_ASSIGNMENT((#110,#115));
141+
#110 = SURFACE_STYLE_USAGE(.BOTH.,#111);
142+
#111 = SURFACE_SIDE_STYLE('',(#112));
143+
#112 = SURFACE_STYLE_FILL_AREA(#113);
144+
#113 = FILL_AREA_STYLE('',(#114));
145+
#114 = FILL_AREA_STYLE_COLOUR('',#103);
146+
#115 = CURVE_STYLE('',#116,POSITIVE_LENGTH_MEASURE(0.1),#106);
147+
#116 = DRAUGHTING_PRE_DEFINED_CURVE_FONT('continuous');
148+
ENDSEC;
149+
END-ISO-10303-21;
18.6 KB
Binary file not shown.

0 commit comments

Comments
 (0)