Skip to content

Commit cf7e403

Browse files
authored
copyright update
1 parent c4a0553 commit cf7e403

16 files changed

+5556
-5556
lines changed

Code/spomso/spomso/cores/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright (C) 2024 Peter Ropač
1+
# Copyright (C) 2025 Peter Ropač
22
# This file is part of SPOMSO.
33
# SPOMSO is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
44
# SPOMSO is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
Lines changed: 158 additions & 158 deletions
Original file line numberDiff line numberDiff line change
@@ -1,158 +1,158 @@
1-
# Copyright (C) 2024 Peter Ropač
2-
# This file is part of SPOMSO.
3-
# SPOMSO is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
4-
# SPOMSO is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
5-
# You should have received a copy of the GNU Lesser General Public License along with SPOMSO. If not, see <https://www.gnu.org/licenses/>.
6-
7-
import numpy as np
8-
from spomso.cores.geom import GenericGeometry
9-
from typing import Callable
10-
11-
def smoothmin_poly2(x, y, a):
12-
# https://iquilezles.org/articles/smin/
13-
h = np.maximum(a - np.abs(x - y), 0.0)/a
14-
return np.minimum(x, y) - h * h * a/4.0
15-
16-
17-
def smoothmin_poly3(x, y, a):
18-
# https://iquilezles.org/articles/smin/
19-
if not a == 0.0:
20-
h = np.maximum(a - np.abs(x - y), 0.0)/a
21-
return np.minimum(x, y) - h * h * h * a / 6.0
22-
else:
23-
return np.minimum(y, y)
24-
25-
26-
def smoothmax_boltz(x, y, width):
27-
# https: // en.wikipedia.org / wiki / Smooth_maximum
28-
exp1 = np.exp(x/width)
29-
exp2 = np.exp(y/width)
30-
31-
return (x*exp1 + y*exp2)/(exp1 + exp2)
32-
33-
34-
class CombineGeometry:
35-
"""Class containing all the possible combination operations which can be applied to a scalar fields.
36-
37-
Attributes:
38-
operations: Dictionary containing all the possible non-parametric operations.
39-
parametric_operations: Dictionary containing all the possible parametric operations.
40-
41-
Args:
42-
operation_type: Type of operation with which two or more geometric objects are combined.
43-
"""
44-
45-
def __init__(self, operation_type: str):
46-
self.operation_type: str = operation_type
47-
self._combined_geometry: Callable[[np.ndarray, tuple], np.ndarray] = None
48-
self.operations: dict = {"UNION2": lambda obj1, obj2: np.minimum(obj1, obj2),
49-
"UNION": lambda *objs: np.amin(objs, axis=0),
50-
"SUBTRACT2": lambda obj1, obj2: np.maximum(obj1, -obj2),
51-
"INTERSECT2": lambda obj1, obj2: np.maximum(obj1, obj2),
52-
"INTERSECT": lambda *objs: np.amax(objs, axis=0),
53-
}
54-
55-
self.parametric_operations: dict = {"SMOOTH_UNION2_2": lambda obj1, obj2, width: smoothmin_poly2(obj1,
56-
obj2,
57-
width),
58-
"SMOOTH_UNION2": lambda obj1, obj2, width: smoothmin_poly3(obj1,
59-
obj2,
60-
width),
61-
"SMOOTH_INTERSECT2": lambda obj1, obj2, width: -smoothmin_poly3(-obj1,
62-
-obj2,
63-
width),
64-
"SMOOTH_INTERSECT2_BOLTZMANN": lambda obj1, obj2, width: smoothmax_boltz(obj1,
65-
obj2,
66-
width),
67-
"SMOOTH_SUBTRACT2": lambda obj1, obj2, width: -smoothmin_poly3(-obj1,
68-
obj2,
69-
width),
70-
"SMOOTH_SUBTRACT2_BOLTZMANN": lambda obj1, obj2, width: smoothmax_boltz(obj1,
71-
-obj2,
72-
width)
73-
}
74-
75-
@property
76-
def available_operations(self) -> list:
77-
"""
78-
Available types of operations.
79-
80-
Returns:
81-
List of available operations.
82-
"""
83-
operations_list = list(self.operations.keys())
84-
print(f"Available non-parametric operations are: {operations_list}")
85-
return operations_list
86-
87-
@property
88-
def available_parametric_operations(self) -> list:
89-
"""
90-
Available types of operations which require a parameter.
91-
92-
Returns:
93-
List of available parametric operations.
94-
"""
95-
operations_list = list(self.parametric_operations.keys())
96-
print(f"Available parametric operations are: {operations_list}")
97-
return operations_list
98-
99-
@property
100-
def combined_geometry(self) -> Callable[[np.ndarray, tuple], np.ndarray]:
101-
"""
102-
Returns the SDF of the combined geometries,
103-
which can be used to create a new geometry using GenericGeometry class.
104-
105-
Returns:
106-
SDF of the combined geometries
107-
"""
108-
return self._combined_geometry
109-
110-
def combine(self, *combined_objects: object) -> GenericGeometry:
111-
"""
112-
Combines 2 or more geometric objects together.
113-
114-
Args:
115-
combined_objects: Tuple containing geometric objects.
116-
117-
Returns:
118-
New geometric object.
119-
"""
120-
if self.operation_type not in self.operations.keys():
121-
raise SyntaxError(f"{self.operation_type} is not an implemented non-parametric operation.",
122-
f"Possible operations are {self.operations.keys}")
123-
124-
def new_geo_object(co, *params):
125-
sdfs = []
126-
for cobject in combined_objects:
127-
sdf_ = cobject.propagate(co, ())
128-
sdfs.append(sdf_)
129-
130-
return self.operations[self.operation_type](*sdfs)
131-
132-
self._combined_geometry = new_geo_object
133-
return GenericGeometry(new_geo_object, ())
134-
135-
def combine_parametric(self, *combined_objects: object, parameters: tuple | float | int) -> GenericGeometry:
136-
"""
137-
Combines 2 or more geometric objects together, based on the parameters of the operations.
138-
Args:
139-
combined_objects: Tuple containing geometric objects.
140-
parameters: Parameters of the operation.
141-
142-
Returns:
143-
New geometric object.
144-
"""
145-
if self.operation_type not in self.parametric_operations.keys():
146-
raise SyntaxError(f"{self.operation_type} is not an implemented parametric operation.",
147-
f"Possible parametric operations are {self.parametric_operations.keys}")
148-
149-
def new_geo_object(co, *params):
150-
sdfs = []
151-
for cobject in combined_objects:
152-
sdf_ = cobject.propagate(co, ())
153-
sdfs.append(sdf_)
154-
155-
return self.parametric_operations[self.operation_type](*sdfs, parameters)
156-
157-
self._combined_geometry = new_geo_object
158-
return GenericGeometry(new_geo_object, ())
1+
# Copyright (C) 2025 Peter Ropač
2+
# This file is part of SPOMSO.
3+
# SPOMSO is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
4+
# SPOMSO is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
5+
# You should have received a copy of the GNU Lesser General Public License along with SPOMSO. If not, see <https://www.gnu.org/licenses/>.
6+
7+
import numpy as np
8+
from spomso.cores.geom import GenericGeometry
9+
from typing import Callable
10+
11+
def smoothmin_poly2(x, y, a):
12+
# https://iquilezles.org/articles/smin/
13+
h = np.maximum(a - np.abs(x - y), 0.0)/a
14+
return np.minimum(x, y) - h * h * a/4.0
15+
16+
17+
def smoothmin_poly3(x, y, a):
18+
# https://iquilezles.org/articles/smin/
19+
if not a == 0.0:
20+
h = np.maximum(a - np.abs(x - y), 0.0)/a
21+
return np.minimum(x, y) - h * h * h * a / 6.0
22+
else:
23+
return np.minimum(y, y)
24+
25+
26+
def smoothmax_boltz(x, y, width):
27+
# https: // en.wikipedia.org / wiki / Smooth_maximum
28+
exp1 = np.exp(x/width)
29+
exp2 = np.exp(y/width)
30+
31+
return (x*exp1 + y*exp2)/(exp1 + exp2)
32+
33+
34+
class CombineGeometry:
35+
"""Class containing all the possible combination operations which can be applied to a scalar fields.
36+
37+
Attributes:
38+
operations: Dictionary containing all the possible non-parametric operations.
39+
parametric_operations: Dictionary containing all the possible parametric operations.
40+
41+
Args:
42+
operation_type: Type of operation with which two or more geometric objects are combined.
43+
"""
44+
45+
def __init__(self, operation_type: str):
46+
self.operation_type: str = operation_type
47+
self._combined_geometry: Callable[[np.ndarray, tuple], np.ndarray] = None
48+
self.operations: dict = {"UNION2": lambda obj1, obj2: np.minimum(obj1, obj2),
49+
"UNION": lambda *objs: np.amin(objs, axis=0),
50+
"SUBTRACT2": lambda obj1, obj2: np.maximum(obj1, -obj2),
51+
"INTERSECT2": lambda obj1, obj2: np.maximum(obj1, obj2),
52+
"INTERSECT": lambda *objs: np.amax(objs, axis=0),
53+
}
54+
55+
self.parametric_operations: dict = {"SMOOTH_UNION2_2": lambda obj1, obj2, width: smoothmin_poly2(obj1,
56+
obj2,
57+
width),
58+
"SMOOTH_UNION2": lambda obj1, obj2, width: smoothmin_poly3(obj1,
59+
obj2,
60+
width),
61+
"SMOOTH_INTERSECT2": lambda obj1, obj2, width: -smoothmin_poly3(-obj1,
62+
-obj2,
63+
width),
64+
"SMOOTH_INTERSECT2_BOLTZMANN": lambda obj1, obj2, width: smoothmax_boltz(obj1,
65+
obj2,
66+
width),
67+
"SMOOTH_SUBTRACT2": lambda obj1, obj2, width: -smoothmin_poly3(-obj1,
68+
obj2,
69+
width),
70+
"SMOOTH_SUBTRACT2_BOLTZMANN": lambda obj1, obj2, width: smoothmax_boltz(obj1,
71+
-obj2,
72+
width)
73+
}
74+
75+
@property
76+
def available_operations(self) -> list:
77+
"""
78+
Available types of operations.
79+
80+
Returns:
81+
List of available operations.
82+
"""
83+
operations_list = list(self.operations.keys())
84+
print(f"Available non-parametric operations are: {operations_list}")
85+
return operations_list
86+
87+
@property
88+
def available_parametric_operations(self) -> list:
89+
"""
90+
Available types of operations which require a parameter.
91+
92+
Returns:
93+
List of available parametric operations.
94+
"""
95+
operations_list = list(self.parametric_operations.keys())
96+
print(f"Available parametric operations are: {operations_list}")
97+
return operations_list
98+
99+
@property
100+
def combined_geometry(self) -> Callable[[np.ndarray, tuple], np.ndarray]:
101+
"""
102+
Returns the SDF of the combined geometries,
103+
which can be used to create a new geometry using GenericGeometry class.
104+
105+
Returns:
106+
SDF of the combined geometries
107+
"""
108+
return self._combined_geometry
109+
110+
def combine(self, *combined_objects: object) -> GenericGeometry:
111+
"""
112+
Combines 2 or more geometric objects together.
113+
114+
Args:
115+
combined_objects: Tuple containing geometric objects.
116+
117+
Returns:
118+
New geometric object.
119+
"""
120+
if self.operation_type not in self.operations.keys():
121+
raise SyntaxError(f"{self.operation_type} is not an implemented non-parametric operation.",
122+
f"Possible operations are {self.operations.keys}")
123+
124+
def new_geo_object(co, *params):
125+
sdfs = []
126+
for cobject in combined_objects:
127+
sdf_ = cobject.propagate(co, ())
128+
sdfs.append(sdf_)
129+
130+
return self.operations[self.operation_type](*sdfs)
131+
132+
self._combined_geometry = new_geo_object
133+
return GenericGeometry(new_geo_object, ())
134+
135+
def combine_parametric(self, *combined_objects: object, parameters: tuple | float | int) -> GenericGeometry:
136+
"""
137+
Combines 2 or more geometric objects together, based on the parameters of the operations.
138+
Args:
139+
combined_objects: Tuple containing geometric objects.
140+
parameters: Parameters of the operation.
141+
142+
Returns:
143+
New geometric object.
144+
"""
145+
if self.operation_type not in self.parametric_operations.keys():
146+
raise SyntaxError(f"{self.operation_type} is not an implemented parametric operation.",
147+
f"Possible parametric operations are {self.parametric_operations.keys}")
148+
149+
def new_geo_object(co, *params):
150+
sdfs = []
151+
for cobject in combined_objects:
152+
sdf_ = cobject.propagate(co, ())
153+
sdfs.append(sdf_)
154+
155+
return self.parametric_operations[self.operation_type](*sdfs, parameters)
156+
157+
self._combined_geometry = new_geo_object
158+
return GenericGeometry(new_geo_object, ())

0 commit comments

Comments
 (0)