From b74891ceb6fc67cc54d26a416a1585a957ada2f3 Mon Sep 17 00:00:00 2001 From: Patrick Sauvan Date: Fri, 20 Dec 2024 13:28:41 +0100 Subject: [PATCH] partial2 --- src/geouned/GEOUNED/core.py | 9 +- src/geouned/GEOUNED/decompose/decom_one.py | 30 +++-- src/geouned/GEOUNED/utils/boolean_function.py | 40 +++--- src/geouned/GEOUNED/utils/functions.py | 116 ++++++++++++------ 4 files changed, 125 insertions(+), 70 deletions(-) diff --git a/src/geouned/GEOUNED/core.py b/src/geouned/GEOUNED/core.py index f7b84034..c1582564 100644 --- a/src/geouned/GEOUNED/core.py +++ b/src/geouned/GEOUNED/core.py @@ -391,7 +391,11 @@ def start(self): # sets self.geometry_bounding_box with default padding self._get_geometry_bounding_box() - self.Surfaces = UF.SurfacesDict(offset=self.settings.startSurf - 1) + self.Surfaces = UF.SurfacesDict(offset=self.settings.startSurf - 1, + options=self.options, + tolerances=self.tolerances, + numeric_format=self.numeric_format + ) warnSolids = [] warnEnclosures = [] @@ -641,9 +645,6 @@ def _decompose_solids(self, meta: bool): self.numeric_format, MakeObj=True, ), - self.options, - self.tolerances, - self.numeric_format, ) m.set_cad_solid() m.update_solids(comsolid.Solids) diff --git a/src/geouned/GEOUNED/decompose/decom_one.py b/src/geouned/GEOUNED/decompose/decom_one.py index 1c353f24..fbed3e62 100644 --- a/src/geouned/GEOUNED/decompose/decom_one.py +++ b/src/geouned/GEOUNED/decompose/decom_one.py @@ -47,7 +47,11 @@ def split_full_cylinder(solid, options, tolerances, numeric_format): def cut_full_cylinder(solid, options, tolerances, numeric_format): solid_gu = GU.SolidGu(solid, tolerances=tolerances) - surfaces = UF.SurfacesDict() + surfaces = UF.SurfacesDict(options=options, + tolerances=tolerances, + numeric_format=numeric_format + ) + flag_inv = CD.is_inverted(solid_gu.solid) universe_box = solid.BoundBox @@ -70,12 +74,12 @@ def cut_full_cylinder(solid, options, tolerances, numeric_format): dim_l = face.ParameterRange[3] - face.ParameterRange[2] cylinder = UF.GeounedSurface(("Cylinder", (orig, dir, rad, dim_l)), universe_box) cylinder.build_surface() - surfaces.add_cylinder(cylinder, options, tolerances, numeric_format, False) + surfaces.add_cylinder(cylinder, False) # add planes if cylinder axis is cut by a plane (plane quasi perpedicular to axis) for p in cyl_bound_planes(solid_gu, face, universe_box): p.build_surface() - surfaces.add_plane(p, options, tolerances, numeric_format, False) + surfaces.add_plane(p, False) break planes = [] @@ -260,7 +264,7 @@ def extract_surfaces(solid, kind, universe_box, options, tolerances, numeric_for plane = UF.GeounedSurface(("Plane", (pos, normal, dim1, dim2)), universe_box) if MakeObj: plane.build_surface() - surfaces.add_plane(plane, options, tolerances, numeric_format, fuzzy) + surfaces.add_plane(plane, fuzzy) elif surf == "": dir = face.Surface.Axis @@ -271,14 +275,14 @@ def extract_surfaces(solid, kind, universe_box, options, tolerances, numeric_for cylinder = UF.GeounedSurface(("Cylinder", (orig, dir, rad, dim_l)), universe_box) if MakeObj: cylinder.build_surface() - surfaces.add_cylinder(cylinder, options, tolerances, numeric_format, fuzzy) + surfaces.add_cylinder(cylinder, fuzzy) if kind in ["Planes", "All"]: # add planes if cylinder axis is cut by a plane (plane quasi perpedicular to axis) for p in cyl_bound_planes(solid_GU, face, universe_box): if MakeObj: p.build_surface() - surfaces.add_plane(p, options, tolerances, numeric_format, False) + surfaces.add_plane(p, False) elif surf == "": dir = face.Surface.Axis @@ -290,13 +294,13 @@ def extract_surfaces(solid, kind, universe_box, options, tolerances, numeric_for cone = UF.GeounedSurface(("Cone", (apex, dir, half_angle, dim_l, dimR)), universe_box) if MakeObj: cone.build_surface() - surfaces.add_cone(cone, tolerances) + surfaces.add_cone(cone) if kind in ["Planes", "All"]: for p in cyl_bound_planes(solid_GU, face, universe_box): if MakeObj: p.build_surface() - surfaces.add_plane(p, options, tolerances, numeric_format, False) + surfaces.add_plane(p, False) elif surf[0:6] == "Sphere" and kind in ["Sph", "All"]: rad = face.Surface.Radius @@ -304,13 +308,13 @@ def extract_surfaces(solid, kind, universe_box, options, tolerances, numeric_for sphere = UF.GeounedSurface(("Sphere", (pnt, rad)), universe_box) if MakeObj: sphere.build_surface() - surfaces.add_sphere(sphere, tolerances) + surfaces.add_sphere(sphere) if kind in ["Planes", "All"]: for p in cyl_bound_planes(solid_GU, face, universe_box): if MakeObj: p.build_surface() - surfaces.add_plane(p, options, tolerances, numeric_format, False) + surfaces.add_plane(p, False) elif surf == "": if kind in ["Tor", "All"]: @@ -321,13 +325,13 @@ def extract_surfaces(solid, kind, universe_box, options, tolerances, numeric_for torus = UF.GeounedSurface(("Torus", (center, dir, radMaj, radMin)), universe_box) if MakeObj: torus.build_surface() - surfaces.add_torus(torus, tolerances) + surfaces.add_torus(torus) if kind in ["Planes", "All"]: for p in torus_bound_planes(solid_GU, face, universe_box, tolerances): if MakeObj: p.build_surface() - surfaces.add_plane(p, options, tolerances, numeric_format, False) + surfaces.add_plane(p, False) elif surf == "" and kind == "Plane3Pts": pos = face.CenterOfMass @@ -339,7 +343,7 @@ def extract_surfaces(solid, kind, universe_box, options, tolerances, numeric_for plane = UF.GeounedSurface(("Plane3Pts", (pos, normal, dim1, dim2, points)), universe_box) if MakeObj: plane.build_surface() - surfaces.add_plane(plane, options, tolerances, numeric_format, fuzzy) + surfaces.add_plane(plane, fuzzy) return surfaces diff --git a/src/geouned/GEOUNED/utils/boolean_function.py b/src/geouned/GEOUNED/utils/boolean_function.py index 80c9846c..9da2a699 100644 --- a/src/geouned/GEOUNED/utils/boolean_function.py +++ b/src/geouned/GEOUNED/utils/boolean_function.py @@ -21,9 +21,14 @@ def __new__(cls, *args, **kwrds): def __init__(self, label, definition=None): if definition is None: self.definition = BoolSequence(str(label)) + self.level = 0 else: self.definition = definition - self.surfaces = self.definition.get_surfaces_numbers(self) + self.level = definition.level + self.surfaces = self.definition.get_surfaces_numbers() + + def __str__(self): + return self.definition.__str__() def __neg__(self): return BoolRegion(-self.__int__(), self.definition.get_complementary()) @@ -57,7 +62,11 @@ def __mul__(self, def2): def setDef(self, definition): self.definition = definition - self.surfaces = self.definition.get_surfaces_numbers(self) + self.surfaces = self.definition.get_surfaces_numbers() + self.level = definition.level + + def level_update(self): + pass def copy(self, newname): return BoolRegion(newname, self.definition) @@ -80,7 +89,7 @@ def __str__(self): if type(self.elements) is bool: return " True " if self.elements else " False " for e in self.elements: - if type(e) is int or type(e) is bool or type(e) is str: + if isinstance(e, (bool,int)): out += f" {e} " else: out += e.__str__() @@ -92,16 +101,17 @@ def append(self, *seq): """Append a BoolSequence Objects. seq may be : - An iterable containing allowed BoolSequence Objects - A BoolSequence object - - An integer value + - An BoolRegion object + - An integer - A Boolean value""" - if type(self.elements) is bool: + if isinstance(self.elements, bool): if (self.elements and self.operator == "AND") or (not self.elements and self.operator == "OR"): self.assign(seq) return for s in seq: - if type(s) is int: + if isinstance(s,(int,BoolRegion)): level = -1 if s in self.elements: continue @@ -112,16 +122,16 @@ def append(self, *seq): else: self.elements = True return - elif type(s) is bool: + elif isinstance(s, bool): if self.operator == "AND" and s or self.operator == "OR" and not s: continue else: self.elements = s self.level = -1 - return + return else: level = s.level - if type(s.elements) is bool: + if isinstance(s.elements, bool): if self.operator == "AND" and not s.elements or self.operator == "OR" and s.elements: self.level = -1 self.elements = s.elements @@ -130,11 +140,11 @@ def append(self, *seq): continue self.elements.append(s) - self.level = max(self.level, level + 1) + self.level_update() def assign(self, seq): """Assign the BoolSequence Seq to the self instance BoolSequence""" - if type(seq) is bool: + if isinstance(seq, bool): self.operator == "AND" self.elements = seq self.level = -1 @@ -158,7 +168,7 @@ def update(self, seq, pos): for i in reversed(indexes): del base.elements[i] - if type(seq.elements) is bool: + if isinstance(seq.elements, bool): base.elements = seq.elements base.level = -1 else: @@ -177,11 +187,11 @@ def copy(self): cp = BoolSequence() cp.operator = self.operator cp.level = self.level - if type(self.elements) is bool: + if isinstance(self.elements, bool): cp.elements = self.elements else: for e in self.elements: - if type(e) is int: + if isinstance(e, int): cp.elements.append(e) else: cp.elements.append(e.copy()) @@ -692,7 +702,7 @@ def level_update(self): self.level = 0 for e in self.elements: - if type(e) is int: + if isinstance(e, int): continue e.level_update() self.level = max(e.level + 1, self.level) diff --git a/src/geouned/GEOUNED/utils/functions.py b/src/geouned/GEOUNED/utils/functions.py index 678547d3..2fecafaa 100644 --- a/src/geouned/GEOUNED/utils/functions.py +++ b/src/geouned/GEOUNED/utils/functions.py @@ -22,6 +22,7 @@ ) from . import basic_functions_part2 as BF +from .data_classes import NumericFormat, Options, Tolerances def get_box(comp, enlargeBox): bb = FreeCAD.BoundBox(comp.BoundBox) @@ -326,8 +327,17 @@ def build_surface(self): class SurfacesDict(dict): - def __init__(self, surfaces=None, offset=0): + def __init__(self, surfaces=None, offset: int = 0, + options: Options = Options(), + tolerances: Tolerances = Tolerances(), + numeric_format: NumericFormat = NumericFormat(), + ): + self.IndexOffset = offset + self.options = options + self.tolerance = tolerances + self.numeric_format = numeric_format + surfname = ["PX", "PY", "PZ", "P", "Cyl", "Cone", "Sph", "Tor"] for name in surfname: self[name] = [] @@ -339,9 +349,14 @@ def __init__(self, surfaces=None, offset=0): self[key] = surfaces[key][:] self.__surfIndex__[key] = surfaces.__surfIndex__[key][:] self.surfaceNumber = surfaces.surfaceNumber + self.metaSurfaceNumber = surfaces.metaSurfaceNumber + self.options = surfaces.options + self.tolerance = surfaces.tolerance + self.numeric_format = surfaces.numeric_format self.__last_obj__ = (surfaces.__last_obj__[0], surfaces.__last_obj__[1]) else: self.surfaceNumber = 0 + self.metaSurfaceNumber = 0 self.__last_obj__ = ("", -1) for key in surfname: self.__surfIndex__[key] = [] @@ -377,33 +392,35 @@ def del_surface(self, index): del self[self.__last_obj__[0]][self.__last_obj__[1]] return - def extend(self, surface, options, tolerances, numeric_format): + def extend(self, surface): for Pkey in ["PX", "PY", "PZ", "P"]: for s in surface[Pkey]: - self.add_plane(s, options, tolerances, numeric_format, False) + self.add_plane(s, False) for s in surface["Cyl"]: - self.add_cylinder(s, options, tolerances, numeric_format, False) + self.add_cylinder(s, False) for s in surface["Cone"]: - self.add_cone(s, tolerances) + self.add_cone(s) for s in surface["Sph"]: - self.add_sphere(s, tolerances) + self.add_sphere(s) for s in surface["Tor"]: - self.add_torus(s, tolerances) + self.add_torus(s) + + - def add_plane(self, plane, options, tolerances, numeric_format, fuzzy): + def add_plane(self, plane, fuzzy): ex = FreeCAD.Vector(1, 0, 0) ey = FreeCAD.Vector(0, 1, 0) ez = FreeCAD.Vector(0, 0, 1) - if is_parallel(plane.Surf.Axis, ex, tolerances.pln_angle): + if is_parallel(plane.Surf.Axis, ex, self.tolerances.pln_angle): add_plane = True for i, p in enumerate(self["PX"]): if BF.is_same_plane( plane.Surf, p.Surf, - options=options, - tolerances=tolerances, - numeric_format=numeric_format, + options=self.options, + tolerances=self.tolerances, + numeric_format=self.numeric_format, fuzzy=(fuzzy, p.Index), ): add_plane = False @@ -417,15 +434,15 @@ def add_plane(self, plane, options, tolerances, numeric_format, fuzzy): self["PX"].append(plane) self.__surfIndex__["PX"].append(plane.Index) - elif is_parallel(plane.Surf.Axis, ey, tolerances.pln_angle): + elif is_parallel(plane.Surf.Axis, ey, self.tolerances.pln_angle): add_plane = True for i, p in enumerate(self["PY"]): if BF.is_same_plane( plane.Surf, p.Surf, - options=options, - tolerances=tolerances, - numeric_format=numeric_format, + options=self.options, + tolerances=self.tolerances, + numeric_format=self.numeric_format, fuzzy=(fuzzy, p.Index), ): add_plane = False @@ -439,15 +456,15 @@ def add_plane(self, plane, options, tolerances, numeric_format, fuzzy): self["PY"].append(plane) self.__surfIndex__["PY"].append(plane.Index) - elif is_parallel(plane.Surf.Axis, ez, tolerances.pln_angle): + elif is_parallel(plane.Surf.Axis, ez, self.tolerances.pln_angle): add_plane = True for i, p in enumerate(self["PZ"]): if BF.is_same_plane( plane.Surf, p.Surf, - options=options, - tolerances=tolerances, - numeric_format=numeric_format, + options=self.options, + tolerances=self.tolerances, + numeric_format=self.numeric_format, fuzzy=(fuzzy, p.Index), ): add_plane = False @@ -467,9 +484,9 @@ def add_plane(self, plane, options, tolerances, numeric_format, fuzzy): if BF.is_same_plane( plane.Surf, p.Surf, - options=options, - tolerances=tolerances, - numeric_format=numeric_format, + options=self.options, + tolerances=self.tolerances, + numeric_format=self.numeric_format, fuzzy=(fuzzy, p.Index), ): add_plane = False @@ -488,15 +505,15 @@ def add_plane(self, plane, options, tolerances, numeric_format, fuzzy): else: return index, True - def add_cylinder(self, cyl, options, tolerances, numeric_format, fuzzy=False): + def add_cylinder(self, cyl, fuzzy=False): addCyl = True for i, c in enumerate(self["Cyl"]): if BF.is_same_cylinder( cyl.Surf, c.Surf, - options=options, - tolerances=tolerances, - numeric_format=numeric_format, + options=self.options, + tolerances=self.tolerances, + numeric_format=self.numeric_format, fuzzy=(fuzzy, c.Index), ): addCyl = False @@ -514,15 +531,15 @@ def add_cylinder(self, cyl, options, tolerances, numeric_format, fuzzy=False): else: return index, True - def add_cone(self, cone, tolerances): + def add_cone(self, cone): cone_added = True for i, c in enumerate(self["Cone"]): if BF.is_same_cone( cone.Surf, c.Surf, - dtol=tolerances.kne_distance, - atol=tolerances.kne_angle, - rel_tol=tolerances.relativeTol, + dtol=self.tolerances.kne_distance, + atol=self.tolerances.kne_angle, + rel_tol=self.tolerances.relativeTol, ): cone_added = False index = c.Index @@ -538,14 +555,14 @@ def add_cone(self, cone, tolerances): else: return index, True - def add_sphere(self, sph, tolerances): + def add_sphere(self, sph): sphere_added = True for i, s in enumerate(self["Sph"]): if BF.is_same_sphere( sph.Surf, s.Surf, - tolerances.sph_distance, - rel_tol=tolerances.relativeTol, + self.tolerances.sph_distance, + rel_tol=self.tolerances.relativeTol, ): sphere_added = False index = s.Index @@ -561,15 +578,15 @@ def add_sphere(self, sph, tolerances): else: return index, True - def add_torus(self, tor, tolerances): + def add_torus(self, tor): add_torus = True for i, s in enumerate(self["Tor"]): if BF.is_same_torus( tor.Surf, s.Surf, - dtol=tolerances.tor_distance, - atol=tolerances.tor_angle, - rel_tol=tolerances.relativeTol, + dtol=self.tolerances.tor_distance, + atol=self.tolerances.tor_angle, + rel_tol=self.tolerances.relativeTol, ): add_torus = False index = s.Index @@ -585,6 +602,29 @@ def add_torus(self, tor, tolerances): else: return index, True + def add_metaplane(self, mp, fuzzy=False): + add_metap = True + for i, s in enumerate(self["Metap"]): + if BF.is_same_metaplane( + mp, + s, + dtol=self.tolerances.tor_distance, + atol=self.tolerances.tor_angle, + rel_tol=self.tolerances.relativeTol, + ): + add_metap = False + index = s.Index + self.__last_obj__ = ("Tor", i) + break + if add_metap: + self.surfaceNumber += 1 + mp.Index = self.surfaceNumber + self.IndexOffset + self.__last_obj__ = ("Metap", len(self["Metap"])) + self["Metap"].append(mp) + self.__surfIndex__["Metap"].append(mp.Index) + return mp.Index, False + else: + return index, True def split_bop(solid, tools, tolerance, options, scale=0.1):