1 # -*- coding: utf-8 -*-
3 # Copyright (C) 2007-2009 EDF R&D
5 # This file is part of PAL_SRC.
7 # PAL_SRC is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 2 of the License, or
10 # (at your option) any later version.
12 # PAL_SRC is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with PAL_SRC; if not, write to the Free Software
19 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 This module is used to compute the orientation of the different parts in a
23 structural element and to build the corresponding markers (trihedrons).
28 from salome.kernel.logger import Logger
29 from salome.kernel import termcolor
30 logger = Logger("__PAL_GEOM__.structelem.orientation", color = termcolor.RED)
35 This class is used to compute the orientation of 1D elements and to build
36 the corresponding markers.
41 self._vectorYCoords = None
45 reprdict = self.__dict__.copy()
47 return '%s(%s)' % (self.__class__.__name__, reprdict)
49 def addParams(self, params):
51 Add orientation parameters. `params` is a dictionary containing one or
52 several orientation parameters. The valid parameters are:
54 * "VECT_Y": Triplet defining the local Y axis (the X axis is the
55 main direction of the 1D element).
56 * "ANGL_VRIL": Angle of rotation along the X axis to define the local
59 The parameters can be specified several times. In this case, only the
60 first "VECT_Y" is taken into account, and the values of "ANGL_VRIL"
61 are added to obtain the total rotation angle.
63 mydict = params.copy()
64 if mydict.has_key("VECT_Y"):
65 newVecCoords = mydict.pop("VECT_Y")
66 if self._vectorYCoords is None:
67 logger.debug("Setting orientation vector Y to %s" %
69 self._vectorYCoords = newVecCoords
71 logger.warning('Orientation parameter "VECT_Y" is specified '
72 'several times for the same mesh group, vector'
73 ' %s will be used' % str(self._vectorYCoords))
74 if mydict.has_key("ANGL_VRIL"):
75 newAngle = mydict.pop("ANGL_VRIL")
76 self._angle += newAngle
77 logger.debug("Adding angle %f to orientation, new angle is %f." %
78 (newAngle, self._angle))
80 logger.warning("Invalid orientation parameter(s) (ignored): %s" %
83 def _buildDefaultMarker(self, center, vecX):
85 Create the default marker, that use the main direction of the 1D
86 object as the local X axis and the global Z axis to determine the
89 xPoint = self.geom.MakeTranslationVector(center, vecX)
90 givenVecZ = self.geom.MakeVectorDXDYDZ(0.0, 0.0, 1.0)
91 angle = self.geom.GetAngleRadians(vecX, givenVecZ)
92 if abs(angle) < 1e-7 or abs(angle - math.pi) < 1e-7:
93 logger.warning("Beam X axis is colinear to absolute Z axis. "
94 "Absolute X axis will be used to determine "
96 givenVecZ = self.geom.MakeVectorDXDYDZ(1.0, 0.0, 0.0)
97 zPoint = self.geom.MakeTranslationVector(center, givenVecZ)
98 locPlaneZX = self.geom.MakePlaneThreePnt(center, zPoint, xPoint, 1.0)
99 locY = self.geom.GetNormal(locPlaneZX)
100 marker = self.geom.MakeMarkerPntTwoVec(center,vecX,locY)
103 def buildMarker(self, geom, center, vecX):
105 Create a marker with origin `center` and X axis `vecX`. `geom` is the
106 pseudo-geompy object used to build the geometric shapes.
110 if self._vectorYCoords is None:
111 marker = self._buildDefaultMarker(center, vecX)
113 xPoint = self.geom.MakeTranslationVector(center, vecX)
114 givenLocY = self.geom.MakeVectorDXDYDZ(self._vectorYCoords[0],
115 self._vectorYCoords[1],
116 self._vectorYCoords[2])
117 angle = self.geom.GetAngleRadians(vecX, givenLocY)
118 if abs(angle) < 1e-7 or abs(angle - math.pi) < 1e-7:
119 logger.warning("Vector Y is colinear to the beam X axis, "
120 "using default LCS.")
121 marker = self._buildDefaultMarker(center, vecX)
123 yPoint = self.geom.MakeTranslationVector(center, givenLocY)
124 locPlaneXY = self.geom.MakePlaneThreePnt(center, xPoint,
126 locZ = self.geom.GetNormal(locPlaneXY)
127 zPoint = self.geom.MakeTranslationVector(center, locZ)
128 locPlaneZX = self.geom.MakePlaneThreePnt(center, zPoint,
130 locY = self.geom.GetNormal(locPlaneZX)
131 marker = self.geom.MakeMarkerPntTwoVec(center,vecX,locY)
133 if self._angle != 0.0:
134 angleRad = math.radians(self._angle)
135 marker = self.geom.Rotate(marker, vecX, angleRad)
142 This class is used to compute the orientation of 2D elements and to build
143 the corresponding markers. Angles `alpha` and `beta` are used to determine
144 the local coordinate system for the 2D element. If `vect` is not
145 :const:`None`, it is used instead of `alpha` and `beta`.
148 def __init__(self, alpha, beta, vect):
155 reprdict = self.__dict__.copy()
157 return '%s(%s)' % (self.__class__.__name__, reprdict)
159 def _buildDefaultMarker(self, center, normal, warnings = True):
161 Create the default marker, that use the normal vector of the 2D object
162 as the local Z axis and the global X axis to determine the local X
163 axis. `warnings` can be used to enable or disable the logging of
167 globalVecX = self.geom.MakeVectorDXDYDZ(1.0, 0.0, 0.0)
168 angle = self.geom.GetAngleRadians(normal, globalVecX)
169 if abs(angle) < 1e-7 or abs(angle - math.pi) < 1e-7:
171 logger.warning("Face normal is colinear to absolute X axis. "
172 "Absolute Y axis will be used to determine "
174 globalVecY = self.geom.MakeVectorDXDYDZ(0.0, 1.0, 0.0)
175 marker = self._buildMarkerRefVecX(center, normal, globalVecY)
177 marker = self._buildMarkerRefVecX(center, normal, globalVecX)
180 def _buildMarkerRefVecX(self, center, normal, refVecX):
182 Create a marker using `normal` as Z axis and `refVecX` to determine
185 xPoint = self.geom.MakeTranslationVector(center, refVecX)
186 zPoint = self.geom.MakeTranslationVector(center, normal)
187 locPlaneZX = self.geom.MakePlaneThreePnt(center, zPoint, xPoint, 1.0)
188 locY = self.geom.GetNormal(locPlaneZX)
189 yPoint = self.geom.MakeTranslationVector(center, locY)
190 locPlaneYZ = self.geom.MakePlaneThreePnt(center, yPoint, zPoint, 1.0)
191 locX = self.geom.GetNormal(locPlaneYZ)
192 marker = self.geom.MakeMarkerPntTwoVec(center, locX, locY)
195 def buildMarker(self, geom, center, normal, warnings = True):
197 Create a marker with origin `center` and `normal` as Z axis. The other
198 axes are computed using the parameters alpha and beta of the
199 Orientation2D instance. `geom` is the pseudo-geompy object used to
200 build the geometric shapes. `warnings` can be used to enable or
201 disable the logging of warning messages.
206 if self._vect is not None:
207 # Using vector parameter
208 if abs(self._vect[0]) <= 1e-7 and abs(self._vect[1]) <= 1e-7 and \
209 abs(self._vect[2]) <= 1e-7:
211 logger.warning("Vector too small: %s, using default LCS" %
214 refVecX = self.geom.MakeVectorDXDYDZ(self._vect[0],
217 elif self._alpha is not None and self._beta is not None:
218 # Using alpha and beta angles
219 alphaRad = math.radians(self._alpha)
220 betaRad = math.radians(self._beta)
221 if abs(alphaRad) <= 1e-7 and abs(betaRad) <= 1e-7:
223 logger.warning("Angles too small: (%g, %g), using "
224 "default LCS" % (self._alpha, self._beta))
226 # rotate global CS with angles alpha and beta
227 refVecX = self.geom.MakeVectorDXDYDZ(1.0, 0.0, 0.0)
228 refVecY = self.geom.MakeVectorDXDYDZ(0.0, 1.0, 0.0)
229 globalVecZ = self.geom.MakeVectorDXDYDZ(0.0, 0.0, 1.0)
230 if abs(alphaRad) > 1e-7:
231 refVecX = self.geom.Rotate(refVecX, globalVecZ, alphaRad)
232 refVecY = self.geom.Rotate(refVecY, globalVecZ, alphaRad)
233 if abs(betaRad) > 1e-7:
234 refVecX = self.geom.Rotate(refVecX, refVecY, betaRad)
236 if refVecX is not None:
237 # build local coordinate system
238 angle = self.geom.GetAngleRadians(normal, refVecX)
239 if abs(angle) < 1e-7 or abs(angle - math.pi) < 1e-7:
241 logger.warning("Face normal is colinear to the reference "
242 "X axis, using default LCS.")
244 marker = self._buildMarkerRefVecX(center, normal, refVecX)
247 marker = self._buildDefaultMarker(center, normal, warnings)