Skip to content

Commit 721858d

Browse files
committed
template for FFD Cad
1 parent 3bab6de commit 721858d

File tree

5 files changed

+140
-452
lines changed

5 files changed

+140
-452
lines changed

pygem/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ def get_current_year():
2626
from .rbf import RBF
2727
from .idw import IDW
2828
from .rbf_factory import RBFFactory
29+
30+
"""
31+
"""
2932
#from .radial import RBF
3033
#from .idw import IDW
3134
#from .filehandler import FileHandler

pygem/cad/__init__.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11

22
try:
3-
from .nurbshandler import NurbsHandler
4-
from .stephandler import StepHandler
5-
from .igeshandler import IgesHandler
3+
import OCC
64
except ModuleNotFoundError as e:
75
print('\nOCC not found, but required to deal with CAD files')
86
print('Install it using:')
97
print('\tconda install -c conda-forge pythonocc-core=7.4.0')
108
print('or visit https://github.com/tpaviot/pythonocc-core for more info\n')
119
raise e
10+
11+
12+
from .nurbshandler import NurbsHandler
13+
from .stephandler import StepHandler
14+
from .igeshandler import IgesHandler
15+
from .ffd import FFD

pygem/cad/ffd.py

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
"""
2+
Utilities for performing Free Form Deformation (FFD)
3+
4+
:Theoretical Insight:
5+
6+
Free Form Deformation is a technique for the efficient, smooth and accurate
7+
geometrical parametrization. It has been proposed the first time in
8+
*Sederberg, Thomas W., and Scott R. Parry. "Free-form deformation of solid
9+
geometric models." ACM SIGGRAPH computer graphics 20.4 (1986): 151-160*. It
10+
consists in three different step:
11+
12+
- Mapping the physical domain to the reference one with map
13+
:math:`\\boldsymbol{\\psi}`. In the code it is named *transformation*.
14+
15+
- Moving some control points to deform the lattice with :math:`\\hat{T}`.
16+
The movement of the control points is basically the weight (or displacement)
17+
:math:`\\boldsymbol{\\mu}` we set in the *parameters file*.
18+
19+
- Mapping back to the physical domain with map
20+
:math:`\\boldsymbol{\\psi}^{-1}`. In the code it is named
21+
*inverse_transformation*.
22+
23+
FFD map (:math:`T`) is the composition of the three maps, that is
24+
25+
.. math:: T(\\cdot, \\boldsymbol{\\mu}) = (\\Psi^{-1} \\circ \\hat{T} \\circ
26+
\\Psi) (\\cdot, \\boldsymbol{\\mu})
27+
28+
In this way, every point inside the FFD box changes it position according to
29+
30+
.. math:: \\boldsymbol{P} = \\boldsymbol{\\psi}^{-1} \\left( \\sum_{l=0}^L
31+
\\sum_{m=0}^M \\sum_{n=0}^N
32+
\\mathsf{b}_{lmn}(\\boldsymbol{\\psi}(\\boldsymbol{P}_0))
33+
\\boldsymbol{\\mu}_{lmn} \\right)
34+
35+
where :math:`\\mathsf{b}_{lmn}` are Bernstein polynomials. We improve the
36+
traditional version by allowing a rotation of the FFD lattice in order to
37+
give more flexibility to the tool.
38+
39+
You can try to add more shapes to the lattice to allow more and more
40+
involved transformations.
41+
42+
"""
43+
try:
44+
import configparser as configparser
45+
except ImportError:
46+
import ConfigParser as configparser
47+
import os
48+
import numpy as np
49+
from scipy import special
50+
from OCC.Core.TopoDS import TopoDS_Shape, TopoDS_Compound
51+
52+
from pygem import FFD as OriginalFFD
53+
54+
class FFD(OriginalFFD):
55+
"""
56+
Class that handles the Free Form Deformation on the mesh points.
57+
58+
:param FFDParameters ffd_parameters: parameters of the Free Form
59+
Deformation.
60+
:param numpy.ndarray original_mesh_points: coordinates of the original
61+
points of the mesh.
62+
63+
:param list n_control_points: number of control points in the x, y, and z
64+
direction. If not provided it is set to [2, 2, 2].
65+
66+
:cvar numpy.ndarray box_length: dimension of the FFD bounding box, in the
67+
x, y and z direction (local coordinate system).
68+
:cvar numpy.ndarray box_origin: the x, y and z coordinates of the origin of
69+
the FFD bounding box.
70+
:cvar numpy.ndarray rot_angle: rotation angle around x, y and z axis of the
71+
FFD bounding box.
72+
:cvar numpy.ndarray n_control_points: the number of control points in the
73+
x, y, and z direction.
74+
:cvar numpy.ndarray array_mu_x: collects the displacements (weights) along
75+
x, normalized with the box length x.
76+
:cvar numpy.ndarray array_mu_y: collects the displacements (weights) along
77+
y, normalized with the box length y.
78+
:cvar numpy.ndarray array_mu_z: collects the displacements (weights) along
79+
z, normalized with the box length z.
80+
81+
:Example:
82+
83+
>>> import pygem.freeform as ffd
84+
>>> import pygem.params as ffdp
85+
>>> import numpy as np
86+
>>> ffd = FFD()
87+
>>> ffd.read_parameters('tests/test_datasets/parameters_test_ffd_sphere.prm')
88+
# TODO
89+
>>> new = free_form.modified_mesh_points
90+
"""
91+
92+
def __call__(self, obj):
93+
"""
94+
This method performs the deformation on the CAD file.
95+
"""
96+
97+
# Manage input
98+
if isinstance(obj, str): # if a input filename is passed
99+
shape = # extract topo_shape from filename
100+
elif isinstance(obj, TopoDS_Shape):
101+
shape = obj
102+
# Maybe do we need to handle also Compound?
103+
else:
104+
raise TypeError
105+
106+
107+
## SURFACES PHASE #####################################################
108+
src_pts = # extract coordinates of surfaces control points
109+
110+
new_pts = super().__call__(src_pts) # dont touch this line
111+
112+
# save here the `new_pts` into the shape
113+
## END SURFACES #######################################################
114+
115+
116+
117+
## CURVES PHASE #######################################################
118+
src_pts = # extract coordinates of curves control points
119+
120+
new_pts = super().__call__(src_pts) # dont touch this line
121+
122+
# save here the `new_pts` into the shape
123+
## END CURVES #########################################################
124+
125+
126+
127+
if isinstance(obj, str): # if a input filename is passed
128+
# save the shape exactly to the filename, aka `obj`
129+
elif isinstance(obj, TopoDS_Shape):
130+
return shape

0 commit comments

Comments
 (0)